Пример #1
0
        private void ReevaluateCapturedWithinAsync(DependencyObject element, DependencyObject oldParent, bool isCoreParent)
        {
            if (element != null)
            {
                if (_capturedWithinTreeState == null)
                {
                    _capturedWithinTreeState = new DeferredElementTreeState();
                }

                if (isCoreParent)
                {
                    _capturedWithinTreeState.SetCoreParent(element, oldParent);
                }
                else
                {
                    _capturedWithinTreeState.SetLogicalParent(element, oldParent);
                }
            }

            if (_reevaluateCapture == null)
            {
                _reevaluateCapture = Dispatcher.BeginInvoke(DispatcherPriority.Input,
                                                            (DispatcherOperationCallback) delegate(object args)
                {
                    TouchDevice thisRef        = (TouchDevice)args;
                    thisRef._reevaluateCapture = null;
                    thisRef.OnReevaluateCapturedWithinAsync();
                    return(null);
                }, this);
            }
        }
Пример #2
0
        private void ReevaluateDirectlyOverAsync(DependencyObject element, DependencyObject oldParent, bool isCoreParent)
        {
            if (element != null)
            {
                if (_directlyOverTreeState == null)
                {
                    _directlyOverTreeState = new DeferredElementTreeState();
                }

                if (isCoreParent)
                {
                    _directlyOverTreeState.SetCoreParent(element, oldParent);
                }
                else
                {
                    _directlyOverTreeState.SetLogicalParent(element, oldParent);
                }
            }

            if (_reevaluateOver == null)
            {
                _reevaluateOver = Dispatcher.BeginInvoke(DispatcherPriority.Input,
                                                         (DispatcherOperationCallback) delegate(object args)
                {
                    TouchDevice thisRef     = (TouchDevice)args;
                    thisRef._reevaluateOver = null;
                    thisRef.OnHitTestInvalidatedAsync(this, EventArgs.Empty);
                    return(null);
                }, this);
            }
        }
Пример #3
0
        internal void OnOriginValueChanged(DependencyObject oldOrigin,
                                           DependencyObject newOrigin,
                                           IList <DependencyObject> otherOrigins,
                                           ref DeferredElementTreeState oldTreeState,
                                           Action <DependencyObject, bool> originChangedAction)
        {
            DeferredElementTreeState treeStateLocalCopy = oldTreeState;

            oldTreeState = null;

            // Determine if one needs to raise notifications of elements
            // affected by the origin change irrespective of other origins
            bool setOriginCacheFlag = ((originChangedAction != null) &&
                                       (FlagOldOriginCache != CoreFlags.None) &&
                                       (FlagNewOriginCache != CoreFlags.None));

            // Step #1
            // Update the cache flags for all elements in the ancestry
            // of the element that got turned off and record the changed nodes
            if (oldOrigin != null)
            {
                SetCacheFlagInAncestry(oldOrigin, false, treeStateLocalCopy, true, setOriginCacheFlag);
            }

            // Step #2
            // Update the cache flags for all elements in the ancestry
            // of the element that got turned on and record the changed nodes
            if (newOrigin != null)
            {
                SetCacheFlagInAncestry(newOrigin, true, null, true, setOriginCacheFlag);
            }
            int otherCount = (otherOrigins != null) ? otherOrigins.Count : 0;

            for (int i = 0; i < otherCount; i++)
            {
                // setOriginCacheFlag is false, because these flags should not be affected by other origins
                SetCacheFlagInAncestry(otherOrigins[i], true, null, false, /*setOriginCacheFlag*/ false);
            }

            // Step #3
            // Fire value changed on elements in the ancestry of the element that got turned off.
            if (oldOrigin != null)
            {
                FirePropertyChangeInAncestry(oldOrigin, true /* oldValue */, treeStateLocalCopy, originChangedAction);
            }

            // Step #4
            // Fire value changed on elements in the ancestry of the element that got turned on.
            if (newOrigin != null)
            {
                FirePropertyChangeInAncestry(newOrigin, false /* oldValue */, null, originChangedAction);
            }

            if (oldTreeState == null && treeStateLocalCopy != null)
            {
                // Now that we have applied the old tree state, throw it away.
                treeStateLocalCopy.Clear();
                oldTreeState = treeStateLocalCopy;
            }
        }
Пример #4
0
        private void SetCacheFlagInAncestry(DependencyObject element,
                                            bool newValue,
                                            DeferredElementTreeState treeState,
                                            bool shortCircuit,
                                            bool setOriginCacheFlag)
        {
            UIElement      uie;
            ContentElement ce;
            UIElement3D    uie3D;

            CastElement(element, out uie, out ce, out uie3D);

            bool isFlagSet            = IsFlagSet(uie, ce, uie3D, FlagCache);
            bool isFlagOriginCacheSet = (setOriginCacheFlag ? IsFlagSet(uie, ce, uie3D, (newValue ? FlagNewOriginCache : FlagOldOriginCache)) : false);

            // If the cache flag value is undergoing change, record it and
            // propagate the change to the ancestors.
            if ((newValue != isFlagSet) ||
                (setOriginCacheFlag && !isFlagOriginCacheSet) ||
                !shortCircuit)
            {
                if (newValue != isFlagSet)
                {
                    SetFlag(uie, ce, uie3D, FlagCache, newValue);

                    // NOTE: we toggle the changed flag instead of setting it so that that way common
                    // ancestors show resultant unchanged and do not receive any change notification.
                    SetFlag(uie, ce, uie3D, FlagChanged, !IsFlagSet(uie, ce, uie3D, FlagChanged));
                }

                if (setOriginCacheFlag && !isFlagOriginCacheSet)
                {
                    SetFlag(uie, ce, uie3D, (newValue ? FlagNewOriginCache : FlagOldOriginCache), true);
                }

                // Check for block reverse inheritance flag, elements like popup want to set this.
                if (BlockReverseInheritance(uie, ce, uie3D))
                {
                    return;
                }

                // Propagate the flag up the visual and logical trees.  Note our
                // minimal optimization check to avoid walking both the core
                // and logical parents if they are the same.
                {
                    DependencyObject coreParent    = DeferredElementTreeState.GetInputElementParent(element, treeState);
                    DependencyObject logicalParent = DeferredElementTreeState.GetLogicalParent(element, treeState);

                    if (coreParent != null)
                    {
                        SetCacheFlagInAncestry(coreParent, newValue, treeState, shortCircuit, setOriginCacheFlag);
                    }
                    if (logicalParent != null && logicalParent != coreParent)
                    {
                        SetCacheFlagInAncestry(logicalParent, newValue, treeState, shortCircuit, setOriginCacheFlag);
                    }
                }
            }
        }
Пример #5
0
        private void UpdateReverseInheritedProperty(bool capture, IInputElement oldElement, IInputElement newElement)
        {
            // consdier caching the array
            List <DependencyObject> others = null;
            int count = (_activeDevices != null) ? _activeDevices.Count : 0;

            if (count > 0)
            {
                others = new List <DependencyObject>(count);
            }
            for (int i = 0; i < count; i++)
            {
                TouchDevice touchDevice = _activeDevices[i];
                if (touchDevice != this)
                {
                    DependencyObject other = capture ? (touchDevice._captured as DependencyObject) : (touchDevice._directlyOver as DependencyObject);
                    if (other != null)
                    {
                        others.Add(other);
                    }
                }
            }

            ReverseInheritProperty          property            = capture ? (ReverseInheritProperty)UIElement.TouchesCapturedWithinProperty : (ReverseInheritProperty)UIElement.TouchesOverProperty;
            DeferredElementTreeState        treeState           = capture ? _capturedWithinTreeState : _directlyOverTreeState;
            Action <DependencyObject, bool> originChangedAction = capture ? null : RaiseTouchEnterOrLeaveAction;

            property.OnOriginValueChanged(oldElement as DependencyObject, newElement as DependencyObject, others, ref treeState, originChangedAction);

            if (capture)
            {
                _capturedWithinTreeState = treeState;
            }
            else
            {
                _directlyOverTreeState = treeState;
            }
        }
Пример #6
0
        /// <summary>
        ///     Determines if we can remain focused on the element we think has focus
        /// </summary>
        /// <remarks>
        ///     Invoked asynchronously by ReevaluateFocusAsync.
        ///     Confirms that the element we think has focus is:
        ///         - still enabled
        ///         - still visible
        ///         - still in the tree
        /// </remarks>
        private object ReevaluateFocusCallback(object arg)
        {
            _reevaluateFocusOperation = null;

            if (_focus == null)
            {
                return(null);
            }

            //
            // Reevaluate the eligability of the focused element to actually
            // have focus.  If that element is no longer focusable, then search
            // for an ancestor that is.
            //
            DependencyObject element = _focus;

            while (element != null)
            {
                if (Keyboard.IsFocusable(element))
                {
                    break;
                }

                // Walk the current tree structure.
                element = DeferredElementTreeState.GetCoreParent(element, null);
            }

            // Get the PresentationSource that contains the element to be focused.
            PresentationSource presentationSource = null;
            DependencyObject   visualContainer    = InputElement.GetContainingVisual(element);

            if (visualContainer != null)
            {
                presentationSource = PresentationSource.CriticalFromVisual(visualContainer);
            }

            // The default action is to reset focus to the root element
            // of the active presentation source.
            bool             moveFocus   = true;
            DependencyObject moveFocusTo = null;

            if (presentationSource != null)
            {
                IKeyboardInputProvider keyboardProvider = presentationSource.GetInputProvider(typeof(KeyboardDevice)) as IKeyboardInputProvider;
                if (keyboardProvider != null)
                {
                    // Confirm with the keyboard provider for this
                    // presentation source that it has acquired focus.
                    if (keyboardProvider.AcquireFocus(true))
                    {
                        if (element == _focus)
                        {
                            // The focus element is still good.
                            moveFocus = false;
                        }
                        else
                        {
                            // The focus element is no longer focusable, but we found
                            // an ancestor that is, so move focus there.
                            moveFocus   = true;
                            moveFocusTo = element;
                        }
                    }
                }
            }

            if (moveFocus)
            {
                if (moveFocusTo == null && _activeSource != null)
                {
                    moveFocusTo = _activeSource.Value.RootVisual as DependencyObject;
                }


                Focus(moveFocusTo, /*askOld=*/ false, /*askNew=*/ true, /*forceToNullIfFailed=*/ true);
            }
            else
            {
                // Refresh FocusWithinProperty so that ReverseInherited Flags are updated.
                //
                // We only need to do this if there is any information about the old
                // tree structure.
                if (_focusTreeState != null && !_focusTreeState.IsEmpty)
                {
                    UIElement.FocusWithinProperty.OnOriginValueChanged(_focus, _focus, ref _focusTreeState);
                }
            }

            return(null);
        }
Пример #7
0
 internal void OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, ref DeferredElementTreeState oldTreeState)
 {
     OnOriginValueChanged(oldOrigin, newOrigin, null, ref oldTreeState, null);
 }
Пример #8
0
        private void FirePropertyChangeInAncestry(DependencyObject element,
                                                  bool oldValue,
                                                  DeferredElementTreeState treeState,
                                                  Action <DependencyObject, bool> originChangedAction)
        {
            UIElement      uie;
            ContentElement ce;
            UIElement3D    uie3D;

            CastElement(element, out uie, out ce, out uie3D);

            bool flagChanged             = IsFlagSet(uie, ce, uie3D, FlagChanged);
            bool isFlagOldOriginCacheSet = ((FlagOldOriginCache == CoreFlags.None) ? false : IsFlagSet(uie, ce, uie3D, FlagOldOriginCache));
            bool isFlagNewOriginCacheSet = ((FlagNewOriginCache == CoreFlags.None) ? false : IsFlagSet(uie, ce, uie3D, FlagNewOriginCache));

            if (flagChanged || isFlagOldOriginCacheSet || isFlagNewOriginCacheSet)
            {
                if (flagChanged)
                {
                    // if FlagChanged bit is set, then the value has changed effectively
                    // after considering all the origins. Hence change the property value
                    // and fire notifications.
                    SetFlag(uie, ce, uie3D, FlagChanged, false);

                    if (oldValue)
                    {
                        element.ClearValue(FlagKey);
                    }
                    else
                    {
                        element.SetValue(FlagKey, true);
                    }

                    FireNotifications(uie, ce, uie3D, oldValue);
                }

                if (isFlagOldOriginCacheSet || isFlagNewOriginCacheSet)
                {
                    SetFlag(uie, ce, uie3D, FlagOldOriginCache, false);
                    SetFlag(uie, ce, uie3D, FlagNewOriginCache, false);
                    if (isFlagOldOriginCacheSet != isFlagNewOriginCacheSet)
                    {
                        // if either FlagOldOriginCache or FlagNewOriginCache
                        // are set, then the origin change has affected this node
                        // and hence originChangedAction should be executed.
                        Debug.Assert(originChangedAction != null);
                        originChangedAction(element, oldValue);
                    }
                }

                // Check for block reverse inheritance flag, elements like popup want to set this.
                if (BlockReverseInheritance(uie, ce, uie3D))
                {
                    return;
                }

                // Call FirePropertyChange up the visual and logical trees.
                // Note our minimal optimization check to avoid walking both
                // the core and logical parents if they are the same.
                {
                    DependencyObject coreParent    = DeferredElementTreeState.GetInputElementParent(element, treeState);
                    DependencyObject logicalParent = DeferredElementTreeState.GetLogicalParent(element, treeState);

                    if (coreParent != null)
                    {
                        FirePropertyChangeInAncestry(coreParent, oldValue, treeState, originChangedAction);
                    }
                    if (logicalParent != null && logicalParent != coreParent)
                    {
                        FirePropertyChangeInAncestry(logicalParent, oldValue, treeState, originChangedAction);
                    }
                }
            }
        }