예제 #1
0
        private static List <MeasurementResult> FindCandidatesInGroup(DirectionFunction function, Rect focusedBounds, AutomationElement group, System.Windows.Automation.Condition condition)
        {
            var results  = new List <MeasurementResult>();
            var children = group.FindAll(TreeScope.Children, condition)?.Cast <AutomationElement>();

            if (children == null)
            {
                return(results);
            }

            AutomationElement candidate           = null;
            double            nearestItemDistance = double.PositiveInfinity;

            foreach (var element in children)
            {
                var info         = element.Current;
                var targetBounds = info.BoundingRectangle;
                var controlType  = info.ControlType;

                if (controlType == ControlType.TreeItem)
                {
                    results.AddRange(FindCandidatesInGroup(function, focusedBounds, element, condition));
                }

                if (_ignoreElements.Contains(controlType) || targetBounds == focusedBounds || !function.IsInDirection(targetBounds, focusedBounds) || info.IsOffscreen)
                {
                    continue;
                }

                var distance = function.DistanceCaluculator(targetBounds, focusedBounds, _weightingValue);
                if (!IsFocusable(info, controlType) || targetBounds == _zero)
                {
                    distance = double.PositiveInfinity;
                }

                if (distance < nearestItemDistance && _enumerateTargets.Contains(controlType))
                {
                    nearestItemDistance = distance;
                    candidate           = element;
                }
                else
                {
                    results.AddRange(FindCandidatesInGroup(function, focusedBounds, element, condition));
                }
            }

            if (candidate == null)
            {
                return(results);
            }
            results.Add(new MeasurementResult(candidate, nearestItemDistance));
            return(results);
        }
예제 #2
0
        // Too complex...
        private static List <MeasurementResult> FindCandidates(DirectionFunction function, Rect focusedBounds, AutomationElement root, Unit unit)
        {
            List <MeasurementResult> results = new List <MeasurementResult>();
            var children = root.FindAll(TreeScope.Children, System.Windows.Automation.Condition.TrueCondition)?.Cast <AutomationElement>();

            if (children == null)
            {
                return(results);
            }

            AutomationElement        candidate        = null;
            List <MeasurementResult> candidates       = new List <MeasurementResult>();
            List <AutomationElement> focusedAncestors = new List <AutomationElement>();
            double nearestFocusableDistance           = double.PositiveInfinity;

            foreach (var element in children)
            {
                var info        = element.Current;
                var bounds      = info.BoundingRectangle;
                var controlType = info.ControlType;

                // for WPF(Tab and TabItem)
                if (controlType == ControlType.Tab)
                {
                    focusedAncestors.Add(element);
                }
                else if (controlType == ControlType.TabItem)
                {
                    candidates.Add(new MeasurementResult(element, _weightingValue * 3));
                }

                if (_excludes.Any(x => x == bounds))
                {
                    continue;
                }
                if (bounds.Contains(focusedBounds) || bounds == _zero)
                {
                    focusedAncestors.Add(element);
                    continue;
                }
                if (!function.IsInDirection(bounds, focusedBounds) || bounds == focusedBounds)
                {
                    continue;
                }
                var distance = function.DistanceCaluculator(bounds, focusedBounds, _weightingValue);

                if (unit != Unit.Group || !controlType.IsContainer() || controlType == ControlType.Group)
                {
                    candidates.Add(new MeasurementResult(element, distance));
                }
                if (distance < nearestFocusableDistance)
                {
                    if (_enumerateTargets.Contains(controlType) && IsFocusable(info, controlType))
                    {
                        nearestFocusableDistance = distance;
                        candidate = element;
                    }
                }
            }

            focusedAncestors.ForEach(x => results.AddRange(FindCandidates(function, focusedBounds, x, unit)));
            candidates = candidates.OrderBy(x => x.Distance).ToList();
            foreach (var c in candidates)
            {
                var condition = new PropertyCondition(AutomationElement.IsEnabledProperty, true);
                var result    = FindCandidatesInGroup(function, focusedBounds, c.Element, condition);
                if (result.Count > 0)
                {
                    results.AddRange(result);
                    break;
                }
            }
            if (candidate != null)
            {
                results.Add(new MeasurementResult(candidate, nearestFocusableDistance));
            }
            return(results);
        }