Ejemplo n.º 1
0
        internal GeneralTransform2DTo3D(GeneralTransform transform2D, 
                                        Viewport2DVisual3D containingVisual3D, 
                                        GeneralTransform3D transform3D)
        {            
            Visual child = containingVisual3D.Visual;

            Debug.Assert(child != null, "Going from 2D to 3D containingVisual3D.Visual should not be null");
            
            _transform3D = (GeneralTransform3D)transform3D.GetCurrentValueAsFrozen();

            // we also need to go one more level up to handle a transform being placed
            // on the Viewport2DVisual3D's child
            GeneralTransformGroup transformGroup = new GeneralTransformGroup();
            transformGroup.Children.Add((GeneralTransform)transform2D.GetCurrentValueAsFrozen());
            transformGroup.Children.Add((GeneralTransform)child.TransformToOuterSpace().GetCurrentValueAsFrozen());
            transformGroup.Freeze();
            _transform2D = transformGroup;

            _positions = containingVisual3D.InternalPositionsCache;
            _textureCoords = containingVisual3D.InternalTextureCoordinatesCache;
            _triIndices = containingVisual3D.InternalTriangleIndicesCache;

            _childBounds = child.CalculateSubgraphRenderBoundsOuterSpace();
        }
        /// <summary> 
        /// Constructor
        /// </summary> 
        /// <param name="visual3D">The Visual3D that contains the 2D visual</param> 
        /// <param name="fromVisual">The visual on the Visual3D</param>
        internal GeneralTransform2DTo3DTo2D(Viewport2DVisual3D visual3D, Visual fromVisual) 
        {
            IsInverse = false;

            // get a copy of the geometry information - we store our own model to reuse hit 
            // test code on the GeometryModel3D
            _geometry = new MeshGeometry3D(); 
            _geometry.Positions = visual3D.InternalPositionsCache; 
            _geometry.TextureCoordinates = visual3D.InternalTextureCoordinatesCache;
            _geometry.TriangleIndices = visual3D.InternalTriangleIndicesCache; 
            _geometry.Freeze();

            Visual visual3Dchild = visual3D.Visual;
 
            // Special case - Setting CacheMode on V2DV3D causes an internal switch from using a VisualBrush
            // to using a BitmapCacheBrush.  It also introduces an extra 2D Visual in the Visual tree above 
            // the V2DV3D.Visual, but this extra node has no effect on transforms and can safely be ignored. 
            // The transform returned will be identical to the one created for calling TransformTo* with
            // the V2DV3D.Visual itself. 
            Visual descendentVisual = (fromVisual == visual3Dchild._parent) ? visual3Dchild : fromVisual;

            // get a copy of the size of the visual brush and the rect on the
            // visual that the transform is going to/from 

            _visualBrushBounds = visual3Dchild.CalculateSubgraphRenderBoundsOuterSpace(); 
            _visualBounds = descendentVisual.CalculateSubgraphRenderBoundsInnerSpace(); 

            // get the transform that will let us go from the fromVisual to its last 2D 
            // parent before it reaches the 3D part of the graph (i.e. visual3D.Child)
            GeneralTransformGroup transformGroup = new GeneralTransformGroup();
            transformGroup.Children.Add(descendentVisual.TransformToAncestor(visual3Dchild));
            transformGroup.Children.Add(visual3Dchild.TransformToOuterSpace()); 
            transformGroup.Freeze();
            _transform2D = transformGroup; 
 
            // store the inverse as well
            _transform2DInverse = (GeneralTransform)_transform2D.Inverse; 
            if (_transform2DInverse != null)
            {
                _transform2DInverse.Freeze();
            } 

            // make a copy of the camera and other values on the Viewport3D 
            Viewport3DVisual viewport3D = (Viewport3DVisual)VisualTreeHelper.GetContainingVisual2D(visual3D); 

            _camera = viewport3D.Camera; 
            if (_camera != null)
            {
                _camera = (Camera)viewport3D.Camera.GetCurrentValueAsFrozen();
            } 

            _viewSize = viewport3D.Viewport.Size; 
            _boundingRect = viewport3D.ComputeSubgraphBounds3D(); 
            _objectToViewport = visual3D.TransformToAncestor(viewport3D);
 
            // if the transform was not possible, it could be null - check before freezing
            if (_objectToViewport != null)
            {
                _objectToViewport.Freeze(); 
            }
 
            // store the needed transformations for the various operations 
            _worldTransformation = M3DUtil.GetWorldTransformationMatrix(visual3D);
 
            _validEdgesCache = null;
        }
Ejemplo n.º 3
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
                }

                StylusPlugInCollection currentPic = inputReport.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(inputReport.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);
                    inputReport.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(inputReport.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)
                    {
                        inputReport.StylusDevice.CurrentNonVerifiedTarget = pic;
                        pic.FireEnterLeave(true, rawStylusInput, false);
                    }
                    
                    // We are on the pen thread, just call directly.
                    pic.FireRawStylusInput(rawStylusInput);
                }
            } // lock(__rtiLock)
        }
Ejemplo n.º 4
0
        /// <summary>
        /// The returned matrix can be used to transform coordinates from this Visual to
        /// the specified Visual.
        /// Returns null if no such transform exists due to a non-invertible Transform.
        /// </summary>
        /// <exception cref="ArgumentNullException">If visual is null.</exception>
        /// <exception cref="InvalidOperationException">If the Visuals are not connected.</exception>
        public GeneralTransform TransformToVisual(Visual visual)
        {
            DependencyObject ancestor = FindCommonVisualAncestor(visual);
            Visual ancestorAsVisual = ancestor as Visual;

            if (ancestorAsVisual == null)
            {
                throw new System.InvalidOperationException(SR.Get(SRID.Visual_NoCommonAncestor));
            }

            GeneralTransform g0;
            Matrix m0;

            bool isSimple0 = this.TrySimpleTransformToAncestor(ancestorAsVisual,
                                                               false,
                                                               out g0,
                                                               out m0);

            GeneralTransform g1;
            Matrix m1;

            bool isSimple1 = visual.TrySimpleTransformToAncestor(ancestorAsVisual,
                                                                 true,
                                                                 out g1,
                                                                 out m1);

            // combine the transforms
            // if both transforms are simple Matrix transforms, just multiply them and
            // return the result.
            if (isSimple0 && isSimple1)
            {
                MatrixUtil.MultiplyMatrix(ref m0, ref m1);
                MatrixTransform m = new MatrixTransform(m0);
                m.Freeze();
                return m;
            }

            // Handle the case where 0 is simple and 1 is complex.
            if (isSimple0)
            {
                g0 = new MatrixTransform(m0);
                g0.Freeze();
            }
            else if (isSimple1)
            {
                g1 = new MatrixTransform(m1);
                g1.Freeze();
            }

            // If inverse was requested, TrySimpleTransformToAncestor can return null
            // add the transform only if it is not null
            if (g1 != null)
            {
                GeneralTransformGroup group = new GeneralTransformGroup();
                group.Children.Add(g0);
                group.Children.Add(g1);
                group.Freeze();
                return group;
            }

            return g0;
        }
Ejemplo n.º 5
0
        private 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. 
            }

            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 = rawStylusInputReport.PenContext.Contexts.FindPlugInCollection(newTarget); 
            }
 
            // Make sure any lock() calls do not reenter on us. 
            using(Dispatcher.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: 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(GetTabletToViewTransform(rawStylusInputReport.StylusDevice.TabletDevice))); // 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;
                } 

                // Now fire the confirmed enter/leave events as necessary. 
                StylusPlugInCollection currentTarget = rawStylusInputReport.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(new MatrixTransform(GetTabletToViewTransform(rawStylusInputReport.StylusDevice.TabletDevice))); // 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); 
                    }

                    // Update the verified target.
                    rawStylusInputReport.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); 
                }
 
                // 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.UpdateEventStylusPoints(rawStylusInputReport, true);
                } 
            }
        }