예제 #1
0
        internal void AddStylusPlugInCollection(StylusPlugInCollection pic)
        {
            // must be called from inside of lock(__rtiLock)

            // insert in ZOrder
            _plugInCollectionList.Insert(FindZOrderIndex(pic), pic);
        }
예제 #2
0
        internal StylusPlugInCollection InvokeStylusPluginCollectionForMouse(RawStylusInputReport inputReport, IInputElement directlyOver, StylusPlugInCollection currentPlugInCollection)
        {
            StylusPlugInCollection newPlugInCollection = null;

            // lock to make sure only one event is processed at a time and no changes to state can
            // be made until we finish routing this event.
            lock (__rtiLock)
            {
                //Debug.Assert(inputReport.Actions == RawStylusActions.Down ||
                //             inputReport.Actions == RawStylusActions.Up ||
                //             inputReport.Actions == RawStylusActions.Move);

                // Find new target plugin collection
                if (directlyOver != null)
                {
                    UIElement uiElement = InputElement.GetContainingUIElement(directlyOver as DependencyObject) as UIElement;
                    if (uiElement != null)
                    {
                        newPlugInCollection = FindPlugInCollection(uiElement);
                    }
                }

                // Fire Leave event to old pluginCollection if we need to.
                if (currentPlugInCollection != null && currentPlugInCollection != newPlugInCollection)
                {
                    // NOTE: input report points for mouse are in avalon measured units and not device!
                    RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, currentPlugInCollection.ViewToElement, currentPlugInCollection);

                    currentPlugInCollection.FireEnterLeave(false, tempRawStylusInput, true);

                    // Indicate we've used a stylus plugin
                    _stylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;
                }
                if (newPlugInCollection != null)
                {
                    // NOTE: input report points for mouse are in avalon measured units and not device!
                    RawStylusInput rawStylusInput = new RawStylusInput(inputReport, newPlugInCollection.ViewToElement, newPlugInCollection);
                    inputReport.RawStylusInput = rawStylusInput;

                    if (newPlugInCollection != currentPlugInCollection)
                    {
                        newPlugInCollection.FireEnterLeave(true, rawStylusInput, true);
                    }

                    // We are on the pen thread, just call directly.
                    newPlugInCollection.FireRawStylusInput(rawStylusInput);

                    // Indicate we've used a stylus plugin
                    _stylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;

                    // Fire custom data events (always confirmed for mouse)
                    foreach (RawStylusInputCustomData customData in rawStylusInput.CustomDataList)
                    {
                        customData.Owner.FireCustomData(customData.Data, inputReport.Actions, true);
                    }
                }
            }
            return(newPlugInCollection);
        }
예제 #3
0
        /// <summary>
        /// </summary>
        internal StylusPlugInCollection InvokeStylusPluginCollectionForMouse(RawStylusInputReport inputReport, IInputElement directlyOver, StylusPlugInCollection currentPlugInCollection)
        {
            StylusPlugInCollection newPlugInCollection = null;

            // Find new target plugin collection
            if (directlyOver != null)
            {
                UIElement uiElement = InputElement.GetContainingUIElement(directlyOver as DependencyObject) as UIElement;
                if (uiElement != null)
                {
                    newPlugInCollection = FindPlugInCollection(uiElement);
                }
            }

            // Fire Leave event to old pluginCollection if we need to.
            if (currentPlugInCollection != null && currentPlugInCollection != newPlugInCollection)
            {
                // NOTE: input report points for mouse are in avalon measured units and not device!
                RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, currentPlugInCollection.ViewToElement, currentPlugInCollection);

                currentPlugInCollection.FireEnterLeave(false, tempRawStylusInput, true);

                // Indicate we've used a stylus plugin
                StylusLogic.CurrentStylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;
            }
            if (newPlugInCollection != null)
            {
                // NOTE: input report points for mouse are in avalon measured units and not device!
                RawStylusInput rawStylusInput = new RawStylusInput(inputReport, newPlugInCollection.ViewToElement, newPlugInCollection);
                inputReport.RawStylusInput = rawStylusInput;

                if (newPlugInCollection != currentPlugInCollection)
                {
                    newPlugInCollection.FireEnterLeave(true, rawStylusInput, true);
                }

                // (Comment not applicable until RTI back in) We are on the RTI thread, just call directly.
                newPlugInCollection.FireRawStylusInput(rawStylusInput);

                // Indicate we've used a stylus plugin
                StylusLogic.CurrentStylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;

                // Fire custom data events (always confirmed for mouse)
                foreach (RawStylusInputCustomData customData in rawStylusInput.CustomDataList)
                {
                    customData.Owner.FireCustomData(customData.Data, inputReport.Actions, true);
                }
            }

            return(newPlugInCollection);
        }
예제 #4
0
        internal StylusPlugInCollection TargetPlugInCollection(RawStylusInputReport inputReport)
        {
            // Caller must make call to this routine inside of lock(__rtiLock)!
            StylusPlugInCollection pic = null;

            // We should only be called when not on the application thread!
            System.Diagnostics.Debug.Assert(!inputReport.StylusDevice.CheckAccess());

            WispStylusDevice stylusDevice = inputReport.StylusDevice.As <WispStylusDevice>();

            // We're on the pen thread so can't touch visual tree.  Use capturedPlugIn (if capture on) or cached rects.
            bool elementHasCapture = false;

            pic = stylusDevice.GetCapturedPlugInCollection(ref elementHasCapture);
            int pointLength = inputReport.PenContext.StylusPointDescription.GetInputArrayLengthPerPoint();

            // Make sure that the captured Plugin Collection is still in the list.  CaptureChanges are
            // deferred so there is a window where the stylus device is not updated yet.  This protects us
            // from using a bogus plugin collecton for an element that is in an invalid state.
            if (elementHasCapture && !_plugInCollectionList.Contains(pic))
            {
                elementHasCapture = false;  // force true hittesting to be done!
            }

            if (!elementHasCapture && inputReport.Data != null && inputReport.Data.Length >= pointLength)
            {
                int[] data = inputReport.Data;
                System.Diagnostics.Debug.Assert(data.Length % pointLength == 0);
                Point ptTablet = new Point(data[data.Length - pointLength], data[data.Length - pointLength + 1]);
                // Note: the StylusLogic data inside DeviceUnitsFromMeasurUnits is protected by __rtiLock.
                ptTablet   = ptTablet * stylusDevice.TabletDevice.TabletDeviceImpl.TabletToScreen;
                ptTablet.X = (int)Math.Round(ptTablet.X);                        // Make sure we snap to whole window pixels.
                ptTablet.Y = (int)Math.Round(ptTablet.Y);
                ptTablet   = _stylusLogic.MeasureUnitsFromDeviceUnits(ptTablet); // change to measured units now.

                pic = HittestPlugInCollection(ptTablet);                         // Use cached rectangles for UIElements.
            }
            return(pic);
        }
예제 #5
0
        /// <summary>
        /// Target a plugin collection that either has capture or passes a hit test.
        /// raw input.
        /// </summary>
        /// <param name="inputReport">The raw input to process</param>
        /// <returns>The appropriate collection target</returns>
        internal StylusPlugInCollection TargetPlugInCollection(RawStylusInputReport inputReport)
        {
            StylusPlugInCollection pic = null;

            PointerStylusDevice stylusDevice = inputReport.StylusDevice.As <PointerStylusDevice>();

            bool elementHasCapture = false;

            pic = stylusDevice.GetCapturedPlugInCollection(ref elementHasCapture);

            int pointLength = inputReport.StylusPointDescription.GetInputArrayLengthPerPoint();

            // Make sure that the captured Plugin Collection is still in the list.  CaptureChanges are
            // deferred so there is a window where the stylus device is not updated yet.  This protects us
            // from using a bogus plugin collecton for an element that is in an invalid state.
            if (elementHasCapture && !_plugInCollectionList.Contains(pic))
            {
                elementHasCapture = false;  // force true hittesting to be done!
            }

            if (!elementHasCapture && inputReport.Data != null && inputReport.Data.Length >= pointLength)
            {
                int[] data = inputReport.Data;
                System.Diagnostics.Debug.Assert(data.Length % pointLength == 0);
                Point ptTablet = new Point(data[data.Length - pointLength], data[data.Length - pointLength + 1]);
                // Note: the StylusLogic data inside DeviceUnitsFromMeasurUnits is protected by __rtiLock.
                ptTablet   = ptTablet * stylusDevice.TabletDevice.TabletDeviceImpl.TabletToScreen;
                ptTablet.X = (int)Math.Round(ptTablet.X);                                   // Make sure we snap to whole window pixels.
                ptTablet.Y = (int)Math.Round(ptTablet.Y);
                ptTablet  *= inputReport.InputSource.CompositionTarget.TransformFromDevice; // change to measured units now.

                pic = HittestPlugInCollection(ptTablet);                                    // Use cached rectangles for UIElements.
            }

            return(pic);
        }
        /////////////////////////////////////////////////////////////////////
        /// <summary>
        ///     [TBS]
        /// </summary>
        /// <param name="report">[TBS]</param>
        /// <param name="tabletToElementTransform">[TBS]</param>
        /// <param name="targetPlugInCollection">[TBS]</param>
        internal RawStylusInput(
            RawStylusInputReport    report,
            GeneralTransform        tabletToElementTransform,
            StylusPlugInCollection targetPlugInCollection)
        {
            if (report == null)
            {
                throw new ArgumentNullException("report");
            }
            if (tabletToElementTransform.Inverse == null)
            {
                throw new ArgumentException(SR.Get(SRID.Stylus_MatrixNotInvertable), "tabletToElementTransform");
            }
            if (targetPlugInCollection == null)
            {
                throw new ArgumentNullException("targetPlugInCollection");
            }

            // We should always see this GeneralTransform is frozen since we access this from multiple threads.
            System.Diagnostics.Debug.Assert(tabletToElementTransform.IsFrozen);
            _report                 = report;
            _tabletToElementTransform  = tabletToElementTransform;
            _targetPlugInCollection = targetPlugInCollection;
        }
예제 #7
0
 internal void RemoveStylusPlugInCollection(StylusPlugInCollection pic)
 {
     // must be called from inside of lock(__rtiLock)
     _plugInCollectionList.Remove(pic);
 }
예제 #8
0
        internal void InvokeStylusPluginCollection(RawStylusInputReport inputReport)
        {
            // Find PenContexts object for this inputReport.
            StylusPlugInCollection pic = null;

            // lock to make sure only one event is processed at a time and no changes to state can
            // be made until we finish routing this event.
            lock (__rtiLock)
            {
                switch (inputReport.Actions)
                {
                case RawStylusActions.Down:
                case RawStylusActions.Move:
                case RawStylusActions.Up:
                    // Figure out current target plugincollection.
                    pic = TargetPlugInCollection(inputReport);
                    break;

                default:
                    return;     // Nothing to do unless one of the above events
                }

                WispStylusDevice stylusDevice = inputReport.StylusDevice.As <WispStylusDevice>();

                StylusPlugInCollection currentPic = stylusDevice.CurrentNonVerifiedTarget;

                // Fire Leave event if we need to.
                if (currentPic != null && currentPic != pic)
                {
                    // Create new RawStylusInput to send
                    GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
                    transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
                    transformTabletToView.Children.Add(currentPic.ViewToElement);                                                              // Make it relative to the element.
                    transformTabletToView.Freeze();                                                                                            // Must be frozen for multi-threaded access.

                    RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, transformTabletToView, currentPic);

                    currentPic.FireEnterLeave(false, tempRawStylusInput, false);

                    // Indicate we've used a stylus plugin
                    _stylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;
                    stylusDevice.CurrentNonVerifiedTarget = null;
                }

                if (pic != null)
                {
                    // NOTE: PenContext info will not change (it gets rebuilt instead so keeping ref is fine)
                    //    The transformTabletToView matrix and plugincollection rects though can change based
                    //    off of layout events which is why we need to lock this.
                    GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
                    transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
                    transformTabletToView.Children.Add(pic.ViewToElement);                                                                     // Make it relative to the element.
                    transformTabletToView.Freeze();                                                                                            // Must be frozen for multi-threaded access.

                    RawStylusInput rawStylusInput = new RawStylusInput(inputReport, transformTabletToView, pic);
                    inputReport.RawStylusInput = rawStylusInput;

                    if (pic != currentPic)
                    {
                        stylusDevice.CurrentNonVerifiedTarget = pic;
                        pic.FireEnterLeave(true, rawStylusInput, false);
                    }

                    // We are on the pen thread, just call directly.
                    pic.FireRawStylusInput(rawStylusInput);

                    // Indicate we've used a stylus plugin
                    _stylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;
                }
            } // lock(__rtiLock)
        }
예제 #9
0
 /// <summary>
 /// Adds a plugin collection in the Z order that its owning element appears graphically
 /// </summary>
 /// <param name="pic"></param>
 internal void AddStylusPlugInCollection(StylusPlugInCollection pic)
 {
     // insert in ZOrder
     _plugInCollectionList.Insert(FindZOrderIndex(pic), pic);
 }
예제 #10
0
        internal int FindZOrderIndex(StylusPlugInCollection spicAdding)
        {
            //should be called inside of lock(__rtiLock)
            DependencyObject spicAddingVisual = spicAdding.Element as Visual;
            int i;

            for (i = 0; i < _plugInCollectionList.Count; i++)
            {
                // first see if parent of node, if it is then we can just scan till we find the
                // first non parent and we're done
                DependencyObject curV = _plugInCollectionList[i].Element as Visual;
                if (VisualTreeHelper.IsAncestorOf(spicAddingVisual, curV))
                {
                    i++;
                    while (i < _plugInCollectionList.Count)
                    {
                        curV = _plugInCollectionList[i].Element as Visual;
                        if (!VisualTreeHelper.IsAncestorOf(spicAddingVisual, curV))
                        {
                            break; // done
                        }
                        i++;
                    }
                    return(i);
                }
                else
                {
                    // Look to see if spicAddingVisual is higher in ZOrder than i, if so then we're done
                    DependencyObject commonParent = VisualTreeHelper.FindCommonAncestor(spicAddingVisual, curV);
                    // If no common parent found then we must have multiple plugincollection elements
                    // that have been removed from the visual tree and we haven't been notified yet of
                    // that change.  In this case just ignore this plugincollection element and go to
                    // the next.
                    if (commonParent == null)
                    {
                        continue;
                    }
                    // If curV is the commonParent we find then we're done.  This new plugin should be
                    // above this one.
                    if (curV == commonParent)
                    {
                        return(i);
                    }
                    // now find first child for each under that common visual that these fall under (not they must be different or common parent is sort of busted.
                    while (VisualTreeHelper.GetParentInternal(spicAddingVisual) != commonParent)
                    {
                        spicAddingVisual = VisualTreeHelper.GetParentInternal(spicAddingVisual);
                    }
                    while (VisualTreeHelper.GetParentInternal(curV) != commonParent)
                    {
                        curV = VisualTreeHelper.GetParentInternal(curV);
                    }
                    // now see which is higher in zorder
                    int count = VisualTreeHelper.GetChildrenCount(commonParent);
                    for (int j = 0; j < count; j++)
                    {
                        DependencyObject child = VisualTreeHelper.GetChild(commonParent, j);
                        if (child == spicAddingVisual)
                        {
                            return(i);
                        }
                        else if (child == curV)
                        {
                            break; // look at next index in _piList.
                        }
                    }
                }
            }

            return(i); // this wasn't higher so return last index.
        }
예제 #11
0
 internal void RemoveStylusPlugInCollection(StylusPlugInCollection pic)
 {
     // must be called from inside of lock(__rtiLock)
     _plugInCollectionList.Remove(pic);
 }
예제 #12
0
 internal void RemoveStylusPlugInCollection(StylusPlugInCollection pic)
 {
     _plugInCollectionList.Remove(pic);
 }
예제 #13
0
        internal StylusPlugInCollection InvokeStylusPluginCollectionForMouse(RawStylusInputReport inputReport, IInputElement directlyOver, StylusPlugInCollection currentPlugInCollection)
        {
            StylusPlugInCollection newPlugInCollection = null;

            // lock to make sure only one event is processed at a time and no changes to state can
            // be made until we finish routing this event.
            lock(__rtiLock)
            {
                //Debug.Assert(inputReport.Actions == RawStylusActions.Down || 
                //             inputReport.Actions == RawStylusActions.Up ||
                //             inputReport.Actions == RawStylusActions.Move);
                
                // Find new target plugin collection
                if (directlyOver != null)
                {
                    UIElement uiElement = InputElement.GetContainingUIElement(directlyOver as DependencyObject) as UIElement;
                    if (uiElement != null)
                    {
                        newPlugInCollection = FindPlugInCollection(uiElement);
                    }
                }                

                // Fire Leave event to old pluginCollection if we need to.
                if (currentPlugInCollection != null && currentPlugInCollection != newPlugInCollection)
                {
                    // NOTE: input report points for mouse are in avalon measured units and not device!
                    RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, currentPlugInCollection.ViewToElement, currentPlugInCollection);
                    
                    currentPlugInCollection.FireEnterLeave(false, tempRawStylusInput, true);
                }
                if (newPlugInCollection != null)
                {
                    // NOTE: input report points for mouse are in avalon measured units and not device!
                    RawStylusInput rawStylusInput = new RawStylusInput(inputReport, newPlugInCollection.ViewToElement, newPlugInCollection);
                    inputReport.RawStylusInput = rawStylusInput;

                    if (newPlugInCollection != currentPlugInCollection)
                    {
                        newPlugInCollection.FireEnterLeave(true, rawStylusInput, true);
                    }
                    
                    // We are on the pen thread, just call directly.
                    newPlugInCollection.FireRawStylusInput(rawStylusInput);

                    // Fire custom data events (always confirmed for mouse)
                    foreach (RawStylusInputCustomData customData in rawStylusInput.CustomDataList)
                    {
                        customData.Owner.FireCustomData(customData.Data, inputReport.Actions, true);
                    }
                }
            }
            return newPlugInCollection;
        }
예제 #14
0
 internal int FindZOrderIndex(StylusPlugInCollection spicAdding)
 {
     //should be called inside of lock(__rtiLock)
     DependencyObject spicAddingVisual = spicAdding.Element as Visual;
     int i;
     for (i=0; i < _plugInCollectionList.Count; i++)
     {
         // first see if parent of node, if it is then we can just scan till we find the 
         // first non parent and we're done
         DependencyObject curV = _plugInCollectionList[i].Element as Visual;
         if (VisualTreeHelper.IsAncestorOf(spicAddingVisual, curV))
         {
             i++;
             while (i < _plugInCollectionList.Count)
             {
                 curV = _plugInCollectionList[i].Element as Visual;
                 if (!VisualTreeHelper.IsAncestorOf(spicAddingVisual, curV))
                     break; // done
                 i++;
             }
             return i;
         } 
         else
         {
             // Look to see if spicAddingVisual is higher in ZOrder than i, if so then we're done
             DependencyObject commonParent = VisualTreeHelper.FindCommonAncestor(spicAddingVisual, curV);
             // If no common parent found then we must have multiple plugincollection elements 
             // that have been removed from the visual tree and we haven't been notified yet of
             // that change.  In this case just ignore this plugincollection element and go to 
             // the next.
             if (commonParent == null)
                 continue;
             // If curV is the commonParent we find then we're done.  This new plugin should be
             // above this one.
             if (curV == commonParent)
                 return i;
             // now find first child for each under that common visual that these fall under (not they must be different or common parent is sort of busted.
             while (VisualTreeHelper.GetParentInternal(spicAddingVisual) != commonParent)
                 spicAddingVisual = VisualTreeHelper.GetParentInternal(spicAddingVisual);
             while (VisualTreeHelper.GetParentInternal(curV) != commonParent)
                 curV = VisualTreeHelper.GetParentInternal(curV);
             // now see which is higher in zorder
             int count = VisualTreeHelper.GetChildrenCount(commonParent);
             for (int j = 0; j < count; j++)
             {
                 DependencyObject child = VisualTreeHelper.GetChild(commonParent, j);
                 if (child == spicAddingVisual)
                     return i;
                 else if (child == curV)
                     break; // look at next index in _piList.                        
             }
         }
     }
     
     return i; // this wasn't higher so return last index.
 }
예제 #15
0
        /// <summary>
        /// Verifies that the call to the stylus plugin on the RTI thread was valid against the current visual tree.
        /// If this verification fails, we will rebuild and resend the raw input and custom data in order to inform
        /// the target collections of the error and fix it.
        /// </summary>
        /// <remarks>
        /// This is a remnant of verifying hits to the collections based on the UI thread calling this
        /// after the real time input thread has previously called a collection.  This is due to the RTI thread
        /// not being 100% synchronous with the visual tree in terms of hitting the collections.  This is sort of
        /// redundant right now, but needs to be here when we re-implement the RTI.
        /// </remarks>
        internal void VerifyStylusPlugInCollectionTarget(RawStylusInputReport rawStylusInputReport)
        {
            switch (rawStylusInputReport.Actions)
            {
            case RawStylusActions.Down:
            case RawStylusActions.Move:
            case RawStylusActions.Up:
                break;

            default:
                return;     // do nothing if not Down, Move or Up.
            }

            PointerLogic pointerLogic = StylusLogic.GetCurrentStylusLogicAs <PointerLogic>();

            RawStylusInput originalRSI = rawStylusInputReport.RawStylusInput;
            // See if we have a plugin for the target of this input.
            StylusPlugInCollection targetPIC    = null;
            StylusPlugInCollection targetRtiPIC = (originalRSI != null) ? originalRSI.Target : null;
            bool updateEventPoints = false;

            // Make sure we use UIElement for target if non NULL and hit ContentElement.
            UIElement newTarget = InputElement.GetContainingUIElement(rawStylusInputReport.StylusDevice.DirectlyOver as DependencyObject) as UIElement;

            if (newTarget != null)
            {
                targetPIC = FindPlugInCollection(newTarget);
            }

            // Make sure any lock() calls do not reenter on us.
            using (Dispatcher.CurrentDispatcher.DisableProcessing())
            {
                // See if we hit the wrong PlugInCollection on the pen thread and clean things up if we did.
                if (targetRtiPIC != null && targetRtiPIC != targetPIC && originalRSI != null)
                {
                    // Fire custom data not confirmed events for both pre and post since bad target...
                    foreach (RawStylusInputCustomData customData in originalRSI.CustomDataList)
                    {
                        customData.Owner.FireCustomData(customData.Data, rawStylusInputReport.Actions, false);
                    }

                    updateEventPoints = originalRSI.StylusPointsModified;

                    // Clear RawStylusInput data.
                    rawStylusInputReport.RawStylusInput = null;
                }

                // See if we need to build up an RSI to send to the plugincollection (due to a mistarget).
                bool sendRawStylusInput = false;
                if (targetPIC != null && rawStylusInputReport.RawStylusInput == null)
                {
                    // NOTE: (This applies when RTI is back in) Info will not change (it gets rebuilt instead so keeping ref is fine)
                    //    The transformTabletToView matrix and plugincollection rects though can change based
                    //    off of layout events which is why we need to lock this.
                    GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
                    transformTabletToView.Children.Add(rawStylusInputReport.StylusDevice.As <PointerStylusDevice>().GetTabletToElementTransform(null)); // this gives matrix in measured units (not device)
                    transformTabletToView.Children.Add(targetPIC.ViewToElement);                                                                        // Make it relative to the element.
                    transformTabletToView.Freeze();                                                                                                     // Must be frozen for multi-threaded access.

                    RawStylusInput rawStylusInput = new RawStylusInput(rawStylusInputReport, transformTabletToView, targetPIC);
                    rawStylusInputReport.RawStylusInput = rawStylusInput;
                    sendRawStylusInput = true;
                }

                PointerStylusDevice stylusDevice = rawStylusInputReport.StylusDevice.As <PointerStylusDevice>();

                // Now fire the confirmed enter/leave events as necessary.
                StylusPlugInCollection currentTarget = stylusDevice.CurrentVerifiedTarget;
                if (targetPIC != currentTarget)
                {
                    if (currentTarget != null)
                    {
                        // Fire leave event.  If we never had a plugin for this event then create a temp one.
                        if (originalRSI == null)
                        {
                            GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
                            transformTabletToView.Children.Add(stylusDevice.GetTabletToElementTransform(null)); // this gives matrix in measured units (not device)
                            transformTabletToView.Children.Add(currentTarget.ViewToElement);                    // Make it relative to the element.
                            transformTabletToView.Freeze();                                                     // Must be frozen for multi-threaded access.
                            originalRSI = new RawStylusInput(rawStylusInputReport, transformTabletToView, currentTarget);
                        }
                        currentTarget.FireEnterLeave(false, originalRSI, true);
                    }

                    if (targetPIC != null)
                    {
                        // Fire Enter event
                        targetPIC.FireEnterLeave(true, rawStylusInputReport.RawStylusInput, true);

                        // Indicate we've used a stylus plugin
                        pointerLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;
                    }

                    // Update the verified target.
                    stylusDevice.CurrentVerifiedTarget = targetPIC;
                }

                // Now fire RawStylusInput if needed to the right plugincollection.
                if (sendRawStylusInput)
                {
                    // We are on the pen thread, just call directly.
                    targetPIC.FireRawStylusInput(rawStylusInputReport.RawStylusInput);
                    updateEventPoints = (updateEventPoints || rawStylusInputReport.RawStylusInput.StylusPointsModified);

                    // Indicate we've used a stylus plugin
                    pointerLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;
                }

                // Now fire PrePreviewCustomData events.
                if (targetPIC != null)
                {
                    // Send custom data pre event
                    foreach (RawStylusInputCustomData customData in rawStylusInputReport.RawStylusInput.CustomDataList)
                    {
                        customData.Owner.FireCustomData(customData.Data, rawStylusInputReport.Actions, true);
                    }
                }

                // VerifyRawTarget might resend to correct plugins or may have hit the wrong plugincollection.  The StylusPackets
                // may be overriden in those plugins so we need to call UpdateEventStylusPoints to update things.
                if (updateEventPoints)
                {
                    rawStylusInputReport.StylusDevice.As <PointerStylusDevice>().UpdateEventStylusPoints(rawStylusInputReport, true);
                }
            }
        }
예제 #16
0
 internal void AddStylusPlugInCollection(StylusPlugInCollection pic)
 {
     // must be called from inside of lock(__rtiLock)
     
     // insert in ZOrder
     _plugInCollectionList.Insert(FindZOrderIndex(pic), pic); 
 }
예제 #17
0
        internal void ChangeStylusCapture(IInputElement stylusCapture, CaptureMode captureMode, int timestamp)
        {
            // if the capture changed...
            if (stylusCapture != _stylusCapture)
            {
                // Actually change the capture first.  Invalidate the properties,
                // and then send the events.
                IInputElement oldStylusCapture = _stylusCapture;

                _stylusCapture = stylusCapture;
                _captureMode   = captureMode;

                // We also need to figure out ahead of time if any plugincollections on this captured element (or a parent)
                // for the penthread hittesting code.
                _stylusCapturePlugInCollection = null;

                if (stylusCapture != null)
                {
                    UIElement uiElement = InputElement.GetContainingUIElement(stylusCapture as DependencyObject) as UIElement;
                    if (uiElement != null)
                    {
                        PresentationSource source = PresentationSource.CriticalFromVisual(uiElement as Visual);

                        if (source != null)
                        {
                            PointerStylusPlugInManager manager;

                            if (_pointerLogic.PlugInManagers.TryGetValue(source, out manager))
                            {
                                _stylusCapturePlugInCollection = manager.FindPlugInCollection(uiElement);
                            }
                        }
                    }
                }

                _pointerLogic.UpdateStylusCapture(this, oldStylusCapture, _stylusCapture, timestamp);

                // Send the LostStylusCapture and GotStylusCapture events.
                if (oldStylusCapture != null)
                {
                    StylusEventArgs lostCapture = new StylusEventArgs(StylusDevice, timestamp);
                    lostCapture.RoutedEvent = Stylus.LostStylusCaptureEvent;
                    lostCapture.Source      = oldStylusCapture;
                    InputManager.UnsecureCurrent.ProcessInput(lostCapture);
                }
                if (_stylusCapture != null)
                {
                    StylusEventArgs gotCapture = new StylusEventArgs(StylusDevice, timestamp);
                    gotCapture.RoutedEvent = Stylus.GotStylusCaptureEvent;
                    gotCapture.Source      = _stylusCapture;
                    InputManager.UnsecureCurrent.ProcessInput(gotCapture);
                }

                // Now update the stylus over state (only if this is the current stylus and
                // it is inrange).
                if (_pointerLogic.CurrentStylusDevice == this || InRange)
                {
                    if (_stylusCapture != null)
                    {
                        IInputElement inputElementHit = _stylusCapture;

                        // See if we need to update over for subtree mode.
                        if (CapturedMode == CaptureMode.SubTree && _inputSource != null && _inputSource.Value != null)
                        {
                            Point pt = _pointerLogic.DeviceUnitsFromMeasureUnits(GetPosition(null));
                            inputElementHit = FindTarget(_inputSource.Value, pt);
                        }

                        ChangeStylusOver(inputElementHit);
                    }
                    else
                    {
                        // Only try to update over if we have a valid input source.
                        if (_inputSource != null && _inputSource.Value != null)
                        {
                            Point pt = GetPosition(null);                       // relative to window (root element)
                            pt = _pointerLogic.DeviceUnitsFromMeasureUnits(pt); // change back to device coords.
                            IInputElement currentOver = Input.StylusDevice.GlobalHitTest(_inputSource.Value, pt);
                            ChangeStylusOver(currentOver);
                        }
                    }
                }

                // For Mouse StylusDevice we want to make sure Mouse capture is set up the same.
                if (Mouse.Captured != _stylusCapture || Mouse.CapturedMode != _captureMode)
                {
                    Mouse.Capture(_stylusCapture, _captureMode);
                }
            }
        }
예제 #18
0
 /////////////////////////////////////////////////////////////////////
 // (in Dispatcher)
 internal void Added(StylusPlugInCollection plugInCollection)
 {
     _pic = plugInCollection;
     OnAdded();
     InvalidateIsActiveForInput(); // Make sure we fire OnIsActivateForInputChanged.
 }