@@ -381,6 +381,10 @@ impl NodeWrapper<'_> {
381
381
self . 0 . is_required ( )
382
382
}
383
383
384
+ fn is_scroll_item_pattern_supported ( & self ) -> bool {
385
+ self . 0 . supports_action ( Action :: ScrollIntoView , & filter)
386
+ }
387
+
384
388
pub ( crate ) fn is_selection_item_pattern_supported ( & self ) -> bool {
385
389
match self . 0 . role ( ) {
386
390
// TODO: tables (#29)
@@ -499,6 +503,7 @@ impl NodeWrapper<'_> {
499
503
IInvokeProvider ,
500
504
IValueProvider ,
501
505
IRangeValueProvider ,
506
+ IScrollItemProvider ,
502
507
ISelectionItemProvider ,
503
508
ISelectionProvider ,
504
509
ITextProvider
@@ -603,52 +608,59 @@ impl PlatformNode {
603
608
self . resolve_with_context_for_text_pattern ( |node, _| f ( node) )
604
609
}
605
610
606
- fn do_action < F > ( & self , f : F ) -> Result < ( ) >
611
+ fn do_complex_action < F > ( & self , f : F ) -> Result < ( ) >
607
612
where
608
- F : FnOnce ( ) -> ( Action , Option < ActionData > ) ,
613
+ for < ' a > F : FnOnce ( Node < ' a > ) -> Result < Option < ActionRequest > > ,
609
614
{
610
615
let context = self . upgrade_context ( ) ?;
611
616
if context. is_placeholder . load ( Ordering :: SeqCst ) {
612
- return Ok ( ( ) ) ;
617
+ return Err ( element_not_enabled ( ) ) ;
613
618
}
614
619
let tree = context. read_tree ( ) ;
615
- let node_id = if let Some ( id) = self . node_id {
616
- if !tree. state ( ) . has_node ( id) {
617
- return Err ( element_not_available ( ) ) ;
618
- }
619
- id
620
- } else {
621
- tree. state ( ) . root_id ( )
622
- } ;
623
- drop ( tree) ;
624
- let ( action, data) = f ( ) ;
625
- let request = ActionRequest {
626
- target : node_id,
627
- action,
628
- data,
629
- } ;
630
- context. do_action ( request) ;
620
+ let state = tree. state ( ) ;
621
+ let node = self . node ( state) ?;
622
+ if let Some ( request) = f ( node) ? {
623
+ drop ( tree) ;
624
+ context. do_action ( request) ;
625
+ }
631
626
Ok ( ( ) )
632
627
}
633
628
629
+ fn do_action < F > ( & self , f : F ) -> Result < ( ) >
630
+ where
631
+ F : FnOnce ( ) -> ( Action , Option < ActionData > ) ,
632
+ {
633
+ self . do_complex_action ( |node| {
634
+ if node. is_disabled ( ) {
635
+ return Err ( element_not_enabled ( ) ) ;
636
+ }
637
+ let ( action, data) = f ( ) ;
638
+ Ok ( Some ( ActionRequest {
639
+ target : node. id ( ) ,
640
+ action,
641
+ data,
642
+ } ) )
643
+ } )
644
+ }
645
+
634
646
fn click ( & self ) -> Result < ( ) > {
635
647
self . do_action ( || ( Action :: Click , None ) )
636
648
}
637
649
638
650
fn set_selected ( & self , selected : bool ) -> Result < ( ) > {
639
- self . resolve_with_context ( |node, context | {
651
+ self . do_complex_action ( |node| {
640
652
if node. is_disabled ( ) {
641
653
return Err ( element_not_enabled ( ) ) ;
642
654
}
643
655
let wrapper = NodeWrapper ( & node) ;
644
- if selected != wrapper. is_selected ( ) {
645
- context. do_action ( ActionRequest {
646
- action : Action :: Click ,
647
- target : node. id ( ) ,
648
- data : None ,
649
- } ) ;
656
+ if selected == wrapper. is_selected ( ) {
657
+ return Ok ( None ) ;
650
658
}
651
- Ok ( ( ) )
659
+ Ok ( Some ( ActionRequest {
660
+ action : Action :: Click ,
661
+ target : node. id ( ) ,
662
+ data : None ,
663
+ } ) )
652
664
} )
653
665
}
654
666
@@ -1004,6 +1016,17 @@ patterns! {
1004
1016
} )
1005
1017
}
1006
1018
) ) ,
1019
+ ( UIA_ScrollItemPatternId , IScrollItemProvider , IScrollItemProvider_Impl , is_scroll_item_pattern_supported, ( ) , (
1020
+ fn ScrollIntoView ( & self ) -> Result <( ) > {
1021
+ self . do_complex_action( |node| {
1022
+ Ok ( Some ( ActionRequest {
1023
+ target: node. id( ) ,
1024
+ action: Action :: ScrollIntoView ,
1025
+ data: None ,
1026
+ } ) )
1027
+ } )
1028
+ }
1029
+ ) ) ,
1007
1030
( UIA_SelectionItemPatternId , ISelectionItemProvider , ISelectionItemProvider_Impl , is_selection_item_pattern_supported, ( ) , (
1008
1031
fn IsSelected ( & self ) -> Result <BOOL > {
1009
1032
self . resolve( |node| {
0 commit comments