@@ -392,145 +392,161 @@ impl MidiKeyboard {
392392 /// # Arguments
393393 /// * `config` - Configuration for the MIDI keyboard
394394 pub fn show ( config : MidiKeyboardConfig ) -> impl View {
395- state (
396- move || MidiKeyboardState :: new ( config. clone ( ) ) ,
397- |s, _| {
398- canvas ( move |cx, rect, vger| {
399- // Pre-calculate commonly used values
400- let total_white_keys = cx[ s] . num_white_keys ( ) ;
401- let white_key_width = rect. width ( ) / total_white_keys as f32 ;
402- let key_height = rect. height ( ) ;
403- let black_key_height = key_height * 0.6 ;
404-
405- // Create paint indices once for reuse
406- let white_paint = vger. color_paint ( vger:: Color :: new ( 1.0 , 1.0 , 1.0 , 1.0 ) ) ;
407- let white_held_paint = vger. color_paint ( vger:: Color :: new ( 0.8 , 0.8 , 0.8 , 1.0 ) ) ;
408- let white_hover_paint =
409- vger. color_paint ( vger:: Color :: new ( 0.85 , 0.85 , 0.85 , 1.0 ) ) ;
410- let black_paint = vger. color_paint ( vger:: Color :: new ( 0.1 , 0.1 , 0.1 , 1.0 ) ) ;
411- let black_held_paint = vger. color_paint ( vger:: Color :: new ( 0.3 , 0.3 , 0.3 , 1.0 ) ) ;
412- let black_hover_paint = vger. color_paint ( vger:: Color :: new ( 0.2 , 0.2 , 0.2 , 1.0 ) ) ;
413-
414- // Calculate hovered key using binary search for mouse position
415- let hovered_key_idx = if let Some ( mouse_position) = cx[ s] . mouse_position {
416- Self :: find_hovered_key (
417- & cx[ s] . keyboard_layout ,
418- mouse_position,
419- white_key_width,
420- key_height,
421- black_key_height,
422- )
423- } else {
424- None
425- } ;
426-
427- // Batch render white keys
428- let white_keys: Vec < _ > = cx[ s]
429- . keyboard_layout
430- . iter ( )
431- . enumerate ( )
432- . filter ( |( _, ( _, _, is_black) ) | !is_black)
433- . collect ( ) ;
434-
435- for ( index, ( x, width, _) ) in white_keys {
436- let key_x = x * white_key_width;
437- let key_width = white_key_width * width;
438- let is_held = cx[ s] . keys [ index] . is_some ( ) ;
439- let is_hovered = hovered_key_idx == Some ( index as MidiNoteId ) ;
440-
441- let paint = if is_held {
442- white_held_paint
443- } else if is_hovered {
444- white_hover_paint
395+ focus ( move |has_focus| {
396+ let config = config. clone ( ) ;
397+ state (
398+ move || MidiKeyboardState :: new ( config. clone ( ) ) ,
399+ move |s, _| {
400+ canvas ( move |cx, rect, vger| {
401+ // Pre-calculate commonly used values
402+ let total_white_keys = cx[ s] . num_white_keys ( ) ;
403+ let white_key_width = rect. width ( ) / total_white_keys as f32 ;
404+ let key_height = rect. height ( ) ;
405+ let black_key_height = key_height * 0.6 ;
406+
407+ // Create paint indices once for reuse
408+ let white_paint = vger. color_paint ( vger:: Color :: new ( 1.0 , 1.0 , 1.0 , 1.0 ) ) ;
409+ let white_held_paint =
410+ vger. color_paint ( vger:: Color :: new ( 0.8 , 0.8 , 0.8 , 1.0 ) ) ;
411+ let white_hover_paint =
412+ vger. color_paint ( vger:: Color :: new ( 0.85 , 0.85 , 0.85 , 1.0 ) ) ;
413+ let black_paint = vger. color_paint ( vger:: Color :: new ( 0.1 , 0.1 , 0.1 , 1.0 ) ) ;
414+ let black_held_paint =
415+ vger. color_paint ( vger:: Color :: new ( 0.3 , 0.3 , 0.3 , 1.0 ) ) ;
416+ let black_hover_paint =
417+ vger. color_paint ( vger:: Color :: new ( 0.2 , 0.2 , 0.2 , 1.0 ) ) ;
418+
419+ // Calculate hovered key using binary search for mouse position
420+ let hovered_key_idx = if let Some ( mouse_position) = cx[ s] . mouse_position {
421+ Self :: find_hovered_key (
422+ & cx[ s] . keyboard_layout ,
423+ mouse_position,
424+ white_key_width,
425+ key_height,
426+ black_key_height,
427+ )
445428 } else {
446- white_paint
429+ None
447430 } ;
448431
449- let rect = LocalRect :: new (
450- LocalPoint :: new ( key_x, 0.0 ) ,
451- LocalSize :: new ( key_width, key_height) ,
452- ) ;
453- vger. fill_rect ( rect, 0.0 , paint) ;
454- }
455-
456- // Batch render black keys
457- let black_keys: Vec < _ > = cx[ s]
458- . keyboard_layout
459- . iter ( )
460- . enumerate ( )
461- . filter ( |( _, ( _, _, is_black) ) | * is_black)
462- . collect ( ) ;
463-
464- for ( index, ( x, width, _) ) in black_keys {
465- let key_x = x * white_key_width;
466- let key_width = white_key_width * width;
467- let is_held = cx[ s] . keys [ index] . is_some ( ) ;
468- let is_hovered = hovered_key_idx == Some ( index as MidiNoteId ) ;
469-
470- let paint = if is_held {
471- black_held_paint
472- } else if is_hovered {
473- black_hover_paint
474- } else {
475- black_paint
476- } ;
477-
478- let rect = LocalRect :: new (
479- LocalPoint :: new ( key_x, key_height - black_key_height) ,
480- LocalSize :: new ( key_width, black_key_height) ,
481- ) ;
482- vger. fill_rect ( rect, 0.1 * key_width, paint) ;
483- }
432+ // Batch render white keys
433+ let white_keys: Vec < _ > = cx[ s]
434+ . keyboard_layout
435+ . iter ( )
436+ . enumerate ( )
437+ . filter ( |( _, ( _, _, is_black) ) | !is_black)
438+ . collect ( ) ;
439+
440+ for ( index, ( x, width, _) ) in white_keys {
441+ let key_x = x * white_key_width;
442+ let key_width = white_key_width * width;
443+ let is_held = cx[ s] . keys [ index] . is_some ( ) ;
444+ let is_hovered = hovered_key_idx == Some ( index as MidiNoteId ) ;
445+
446+ let paint = if is_held {
447+ white_held_paint
448+ } else if is_hovered {
449+ white_hover_paint
450+ } else {
451+ white_paint
452+ } ;
453+
454+ let rect = LocalRect :: new (
455+ LocalPoint :: new ( key_x, 0.0 ) ,
456+ LocalSize :: new ( key_width, key_height) ,
457+ ) ;
458+ vger. fill_rect ( rect, 0.0 , paint) ;
459+ }
484460
485- cx[ s] . hovered_key = hovered_key_idx;
486- } )
487- . drag_p (
488- move |cx, local_position, gesture_state, mouse_button| match gesture_state {
489- GestureState :: Began => {
490- if mouse_button == Some ( MouseButton :: Left ) {
491- cx[ s] . mouse_dragging = true ;
492- cx[ s] . current_drag_key = cx[ s] . hovered_key ;
493- if let Some ( current_drag_key) = cx[ s] . current_drag_key {
494- let default_velocity = cx[ s] . config . default_velocity ;
495- let _ = cx[ s] . press_key ( current_drag_key, default_velocity) ;
496- }
497- }
461+ // Batch render black keys
462+ let black_keys: Vec < _ > = cx[ s]
463+ . keyboard_layout
464+ . iter ( )
465+ . enumerate ( )
466+ . filter ( |( _, ( _, _, is_black) ) | * is_black)
467+ . collect ( ) ;
468+
469+ for ( index, ( x, width, _) ) in black_keys {
470+ let key_x = x * white_key_width;
471+ let key_width = white_key_width * width;
472+ let is_held = cx[ s] . keys [ index] . is_some ( ) ;
473+ let is_hovered = hovered_key_idx == Some ( index as MidiNoteId ) ;
474+
475+ let paint = if is_held {
476+ black_held_paint
477+ } else if is_hovered {
478+ black_hover_paint
479+ } else {
480+ black_paint
481+ } ;
482+
483+ let rect = LocalRect :: new (
484+ LocalPoint :: new ( key_x, key_height - black_key_height) ,
485+ LocalSize :: new ( key_width, black_key_height) ,
486+ ) ;
487+ vger. fill_rect ( rect, 0.1 * key_width, paint) ;
498488 }
499- GestureState :: Changed => {
500- if cx[ s] . mouse_position . is_some ( ) {
501- cx[ s] . mouse_position = Some ( local_position) ;
502- if cx[ s] . current_drag_key != cx[ s] . hovered_key {
503- if let Some ( preview_drag_key) = cx[ s] . current_drag_key {
504- let _ = cx[ s] . release_key ( preview_drag_key) ;
505- }
489+
490+ cx[ s] . hovered_key = hovered_key_idx;
491+ } )
492+ // .key(move |cx, k| {
493+ // if has_focus {
494+ // println!("key pressed: {:#?}", k);
495+ // }
496+ // })
497+ // .key_released(move |cx, k| {
498+ // if has_focus {
499+ // println!("key released: {:#?}", k);
500+ // }
501+ // })
502+ . drag_p ( move |cx, local_position, gesture_state, mouse_button| {
503+ match gesture_state {
504+ GestureState :: Began => {
505+ if mouse_button == Some ( MouseButton :: Left ) {
506+ cx[ s] . mouse_dragging = true ;
506507 cx[ s] . current_drag_key = cx[ s] . hovered_key ;
507508 if let Some ( current_drag_key) = cx[ s] . current_drag_key {
508509 let default_velocity = cx[ s] . config . default_velocity ;
509510 let _ = cx[ s] . press_key ( current_drag_key, default_velocity) ;
510511 }
511512 }
512513 }
514+ GestureState :: Changed => {
515+ if cx[ s] . mouse_position . is_some ( ) {
516+ cx[ s] . mouse_position = Some ( local_position) ;
517+ if cx[ s] . current_drag_key != cx[ s] . hovered_key {
518+ if let Some ( preview_drag_key) = cx[ s] . current_drag_key {
519+ let _ = cx[ s] . release_key ( preview_drag_key) ;
520+ }
521+ cx[ s] . current_drag_key = cx[ s] . hovered_key ;
522+ if let Some ( current_drag_key) = cx[ s] . current_drag_key {
523+ let default_velocity = cx[ s] . config . default_velocity ;
524+ let _ =
525+ cx[ s] . press_key ( current_drag_key, default_velocity) ;
526+ }
527+ }
528+ }
529+ }
530+ GestureState :: Ended => {
531+ cx[ s] . mouse_dragging = false ;
532+ cx[ s] . current_drag_key = None ;
533+ cx[ s] . release_not_pressed_keys ( ) ;
534+ }
535+ #[ allow( unreachable_patterns) ]
536+ _ => ( ) ,
513537 }
514- GestureState :: Ended => {
515- cx[ s] . mouse_dragging = false ;
516- cx[ s] . current_drag_key = None ;
517- cx[ s] . release_not_pressed_keys ( ) ;
538+ } )
539+ . hover_p ( move |cx, hover_position| {
540+ cx[ s] . mouse_position = Some ( hover_position) ;
541+ } )
542+ . hover ( move |cx, is_hovering| {
543+ if !is_hovering {
544+ cx[ s] . mouse_position = None ;
518545 }
519- #[ allow( unreachable_patterns) ]
520- _ => ( ) ,
521- } ,
522- )
523- . hover_p ( move |cx, hover_position| {
524- cx[ s] . mouse_position = Some ( hover_position) ;
525- } )
526- . hover ( move |cx, is_hovering| {
527- if !is_hovering {
528- cx[ s] . mouse_position = None ;
529- println ! ( "stopped hovering" ) ;
530- }
531- } )
532- } ,
533- )
546+ } )
547+ } ,
548+ )
549+ } )
534550 }
535551
536552 fn find_hovered_key (
0 commit comments