Example #1
0
 private void Precompute()
 {
     if (VisualFlags.HasFlag(VisualFlags.BBoxDirty))
     {
         Rect rect;
         PrecomputeRecursive(out rect);
     }
 }
Example #2
0
 protected virtual void PrecomputeRecursive(out Rect bboxSubgraph)
 {
     if (VisualFlags.HasFlag(VisualFlags.BBoxDirty))
     {
         PrecomputeContent();
         foreach (var child in VisualChildren)
         {
             Rect rect;
             child.PrecomputeRecursive(out rect);
             _bboxSubgraph = Rect.Union(_bboxSubgraph, rect);
         }
         VisualFlags &= ~VisualFlags.BBoxDirty;
     }
     bboxSubgraph = _bboxSubgraph;
 }
Example #3
0
        /// <summary>
        ///     Walks up the Visual tree setting or clearing the given flags.  Unlike
        ///     PropagateFlags this does not terminate when it reaches node with
        ///     the flags already set.  It always walks all the way to the root.
        /// </summary>
        internal static void SetFlagsToRoot(DependencyObject element, bool value, VisualFlags flags)
        {
            Visual   visual;
            Visual3D visual3D;

            AsVisualInternal(element, out visual, out visual3D);

            if (visual != null)
            {
                visual.SetFlagsToRoot(value, flags);
            }
            else if (visual3D != null)
            {
                visual3D.SetFlagsToRoot(value, flags);
            }
        }
Example #4
0
        //-----------------------------------------------------
        //
        //  Constructors 
        //
        //----------------------------------------------------- 
 
        //------------------------------------------------------
        // 
        //  Public Methods
        //
        //-----------------------------------------------------
 
        //------------------------------------------------------
        // 
        //  Public Properties 
        //
        //------------------------------------------------------ 

        //-----------------------------------------------------
        //
        //  Public Events 
        //
        //------------------------------------------------------ 
 
        //-----------------------------------------------------
        // 
        //  Internal Methods
        //
        //-----------------------------------------------------
 
        #region Internal Methods
 
        /// <summary> 
        ///     This walks up the Visual tree setting the given flags starting at the
        ///     given element. 
        /// </summary>
        internal static void PropagateFlags(
            DependencyObject element,
            VisualFlags flags, 
            VisualProxyFlags proxyFlags)
        { 
            Visual visual; 
            Visual3D visual3D;
 
            AsVisualInternal(element, out visual, out visual3D);

            if (visual != null)
            { 
                Visual.PropagateFlags(visual, flags, proxyFlags);
            } 
            else 
            {
                Visual3D.PropagateFlags(visual3D, flags, proxyFlags); 
            }
        }
Example #5
0
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------

        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

        //------------------------------------------------------
        //
        //  Public Properties
        //
        //------------------------------------------------------

        //------------------------------------------------------
        //
        //  Public Events
        //
        //------------------------------------------------------

        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        /// <summary>
        ///     This walks up the Visual tree setting the given flags starting at the
        ///     given element.
        /// </summary>
        internal static void PropagateFlags(
            DependencyObject element,
            VisualFlags flags,
            VisualProxyFlags proxyFlags)
        {
            Visual   visual;
            Visual3D visual3D;

            AsVisualInternal(element, out visual, out visual3D);

            if (visual != null)
            {
                Visual.PropagateFlags(visual, flags, proxyFlags);
            }
            else
            {
                Visual3D.PropagateFlags(visual3D, flags, proxyFlags);
            }
        }
Example #6
0
        /// <summary>
        ///     Walks up the Visual tree setting or clearing the given flags.  Unlike
        ///     PropagateFlags this does not terminate when it reaches node with
        ///     the flags already set.  It always walks all the way to the root.
        /// </summary>
        internal void SetFlagsToRoot(bool value, VisualFlags flag)
        {
            Visual3D current = this;

            do
            {
                current.SetFlags(value, flag);

                if (current._3DParent == null)
                {
                    VisualTreeUtils.SetFlagsToRoot(InternalVisualParent, value, flag);
                    return;
                }

                current = current._3DParent;
            }
            while (current != null);
        }
Example #7
0
        /// <summary>
        /// Propagates the flags up to the root.
        /// </summary>
        /// <remarks>
        /// The walk stops on a node with all of the required flags set.
        /// </remarks>
        internal static void PropagateFlags(
            Visual e,
            VisualFlags flags,
            VisualProxyFlags proxyFlags)
        {
            while ((e != null) &&
                   (!e.CheckFlagsAnd(flags) || !e.CheckFlagsOnAllChannels(proxyFlags)))
            {
                if (e.CheckFlagsOr(VisualFlags.ShouldPostRender))
                {
                    MediaContext mctx = MediaContext.From(e.Dispatcher);

                    if (mctx.Channel != null)
                    {
                        mctx.PostRender();
                    }
                }
                else if (e.CheckFlagsAnd(VisualFlags.NodeIsCyclicBrushRoot))
                {
                    //
                    // For visuals that are root nodes in visual brushes we
                    // need to fire OnChanged on the owning brushes.
                    //

                    Dictionary<ICyclicBrush, int> cyclicBrushToChannelsMap =
                        CyclicBrushToChannelsMapField.GetValue(e);

                    Debug.Assert(cyclicBrushToChannelsMap != null, "Visual brush roots need to have the visual brush to channels map!");


                    //
                    // Iterate over the visual brushes and fire the OnChanged event.
                    //

                    foreach (ICyclicBrush cyclicBrush in cyclicBrushToChannelsMap.Keys)
                    {
                        cyclicBrush.FireOnChanged();
                    }
                }

                e.SetFlags(true, flags);
                e.SetFlagsOnAllChannels(true, proxyFlags);

                if (e._parent == null)
                {
                    // Stop propagating.  We are at the root of the 2D subtree.
                    return;
                }

                Visual parentAsVisual = e._parent as Visual;
                if (parentAsVisual == null)
                {
                    // if the parent is not null (saw this with earlier null check) and is not a Visual
                    // it must be a Visual3D - continue the propagation
                    Visual3D.PropagateFlags((Visual3D)e._parent, flags, proxyFlags);     
                    return;
                }

                e = parentAsVisual;                
            }
        }
Example #8
0
        /// <summary>
        ///     Check all the children for a bit.
        /// </summary>
        private static bool DoAnyChildrenHaveABitSet(
            Visual pe,
            VisualFlags flag)
        {

            int count = pe.VisualChildrenCount;
            for (int i = 0; i < count; i++)
            {
                Visual v = pe.GetVisualChild(i);
                if (v != null && v.CheckFlagsAnd(flag))
                {
                    return true;
                }
            }

            return false;
        }
Example #9
0
        /// <summary>
        ///     Clean a bit in a Visual node and in all its direct ancestors;
        ///     unless the ancestor also has
        /// </summary>
        /// <param name="e">The Visual Element</param>
        /// <param name="treeFlag">The Flag that marks a sub tree to search</param>
        /// <param name="nodeFlag">The Flag that marks the node to search for.</param>
        internal static void ClearTreeBits(
            DependencyObject e,
            VisualFlags treeFlag,
            VisualFlags nodeFlag)
        {
            Visual eAsVisual;
            Visual3D eAsVisual3D;
            
            // This bit might not be set, but checking costs as much as setting
            // So it is faster to just clear it everytime.
            if (e != null)
            {
                eAsVisual = e as Visual;
                if (eAsVisual != null)
                {
                    eAsVisual.SetFlags(false, nodeFlag);
                }
                else
                {
                    ((Visual3D)e).SetFlags(false, nodeFlag);
                }
            }

            while (e != null)
            {
                eAsVisual = e as Visual;
                if (eAsVisual != null)
                {      
                    if(eAsVisual.CheckFlagsAnd(nodeFlag))
                    {
                        return;  // Done;   if a parent also has the Node bit set.
                    }

                    if(DoAnyChildrenHaveABitSet(eAsVisual, treeFlag))
                    {
                        return;  // Done;   if a other subtrees are set.
                    }

                    eAsVisual.SetFlags(false, treeFlag);
                }
                else
                {
                    eAsVisual3D = e as Visual3D;
                    
                    if(eAsVisual3D.CheckFlagsAnd(nodeFlag))
                    {
                        return;  // Done;   if a parent also has the Node bit set.
                    }

                    if(Visual3D.DoAnyChildrenHaveABitSet(eAsVisual3D, treeFlag))
                    {
                        return;  // Done;   if a other subtrees are set.
                    }

                    eAsVisual3D.SetFlags(false, treeFlag);
                }

                e = VisualTreeHelper.GetParent(e);
            }
        }
Example #10
0
        /// <summary>
        ///     Set a bit in a Visual node and in all its direct ancestors.
        /// </summary>
        /// <param name="e">The Visual Element</param>
        /// <param name="treeFlag">The Flag that marks a sub tree to search</param>
        /// <param name="nodeFlag">The Flag that marks the node to search for.</param>
        internal static void SetTreeBits(
            DependencyObject e,
            VisualFlags treeFlag,
            VisualFlags nodeFlag)
        {
            Visual eAsVisual;
            Visual3D eAsVisual3D;

            if (e != null)
            {
                eAsVisual = e as Visual;
                if (eAsVisual != null)
                {
                    eAsVisual.SetFlags(true, nodeFlag);
                }
                else
                {
                    ((Visual3D)e).SetFlags(true, nodeFlag);
                }
            }

            while (null!=e)
            {
                eAsVisual = e as Visual;
                if (eAsVisual != null)
                {                
                    // if the bit is already set, then we're done.
                    if(eAsVisual.CheckFlagsAnd(treeFlag))
                        return;

                    eAsVisual.SetFlags(true, treeFlag);
                }
                else
                {
                    eAsVisual3D = e as Visual3D;

                    // if the bit is already set, then we're done.
                    if(eAsVisual3D.CheckFlagsAnd(treeFlag))
                        return;

                    eAsVisual3D.SetFlags(true, treeFlag);                    
                }

                e = VisualTreeHelper.GetParent(e);
            }
        }
Example #11
0
 private void SetUIFlags(VisualFlags flags)
 {
     VisualFlags |= flags;
 }
Example #12
0
        /// <summary>
        ///     Check all the children for a bit.
        /// </summary>
        internal static bool DoAnyChildrenHaveABitSet(Visual3D pe,
                                                      VisualFlags flag)
        {

            int count = pe.InternalVisual2DOr3DChildrenCount;
            for (int i = 0; i < count; i++)
            {
                DependencyObject child = pe.InternalGet2DOr3DVisualChild(i);
                                
                Visual v = null;
                Visual3D v3D = null;
                VisualTreeUtils.AsNonNullVisual(child, out v, out v3D);
                
                if (v != null && v.CheckFlagsAnd(flag))
                {
                    return true;
                }
                else if (v3D != null && v3D.CheckFlagsAnd(flag))
                {
                    return true;
                }
            }

            return false;
        }
Example #13
0
 /// <summary>
 /// CheckFlagsAnd returns true if all flags in the bitmask flags are set on the node.
 /// </summary>
 /// <remarks>If there aren't any bits set on the specified flags the method
 /// returns true</remarks>
 internal bool CheckFlagsAnd(VisualFlags flags)
 {
     return (_flags & flags) == flags;
 }
Example #14
0
        /// <summary>
        ///     Finds the first ancestor of the given element which has the given
        ///     flags set.
        /// </summary>
        internal DependencyObject FindFirstAncestorWithFlagsAnd(VisualFlags flag)
        {
            Visual3D current = this;

            do
            {
                if (current.CheckFlagsAnd(flag))
                {
                    // The other Visual crossed through this Visual's parent chain. Hence this is our
                    // common ancestor.
                    return current;
                }

                if (current._3DParent == null)
                {
                    return VisualTreeUtils.FindFirstAncestorWithFlagsAnd(InternalVisualParent, flag);
                }

                current = current._3DParent;
            }
            while (current != null);

            return null;
        }
Example #15
0
        /// <summary>
        ///     Finds the first ancestor of the given element which has the given 
        ///     flags set.
        /// </summary>
        internal static DependencyObject FindFirstAncestorWithFlagsAnd(DependencyObject element, VisualFlags flags)
        { 
            Visual visual;
            Visual3D visual3D; 
 
            AsVisualInternal(element, out visual, out visual3D);
 
            if (visual != null)
            {
                return visual.FindFirstAncestorWithFlagsAnd(flags);
            } 
            else if (visual3D != null)
            { 
                return visual3D.FindFirstAncestorWithFlagsAnd(flags); 
            }
 
            Debug.Assert(element == null);

            return null;
        } 
Example #16
0
 private void ClearFlags(VisualFlags flags)
 {
     VisualFlags &= ~flags;
 }
Example #17
0
        /// <summary>
        ///     Finds the first ancestor of the given element which has the given
        ///     flags set.
        /// </summary>
        internal static DependencyObject FindFirstAncestorWithFlagsAnd(DependencyObject element, VisualFlags flags)
        {
            Visual   visual;
            Visual3D visual3D;

            AsVisualInternal(element, out visual, out visual3D);

            if (visual != null)
            {
                return(visual.FindFirstAncestorWithFlagsAnd(flags));
            }
            else if (visual3D != null)
            {
                return(visual3D.FindFirstAncestorWithFlagsAnd(flags));
            }

            Debug.Assert(element == null);

            return(null);
        }
Example #18
0
 /// <summary>
 /// SetFlags is used to set or unset one or multiple node flags on the node.
 /// </summary>
 internal void SetFlags(bool value, VisualFlags Flags)
 {
     _flags = value ? (_flags | Flags) : (_flags & (~Flags));
 }
Example #19
0
        /// <summary> 
        ///     Walks up the Visual tree setting or clearing the given flags.  Unlike
        ///     PropagateFlags this does not terminate when it reaches node with 
        ///     the flags already set.  It always walks all the way to the root. 
        /// </summary>
        internal static void SetFlagsToRoot(DependencyObject element, bool value, VisualFlags flags) 
        {
            Visual visual;
            Visual3D visual3D;
 
            AsVisualInternal(element, out visual, out visual3D);
 
            if (visual != null) 
            {
                visual.SetFlagsToRoot(value, flags); 
            }
            else if (visual3D != null)
            {
                visual3D.SetFlagsToRoot(value, flags); 
            }
        } 
Example #20
0
 /// <summary>
 /// Checks if any of the specified flags is set on the node.
 /// </summary>
 /// <remarks>If there aren't any bits set on the specified flags the method
 /// returns true</remarks>
 internal bool CheckFlagsOr(VisualFlags flags)
 {
     return (flags == 0) || ((_flags & flags) > 0);
 }
Example #21
0
        /// <summary>
        ///     Walks up the Visual tree setting or clearing the given flags.  Unlike
        ///     PropagateFlags this does not terminate when it reaches node with
        ///     the flags already set.  It always walks all the way to the root.
        /// </summary>
        internal void SetFlagsToRoot(bool value, VisualFlags flag)
        {
            Visual current = this;

            do
            {
                current.SetFlags(value, flag);

                
                Visual currentParent = current._parent as Visual;

                // if the cast to currentParent failed and yet current._parent is not null then
                // we have a 3D element.  Call SetFlagsToRoot on it instead.
                if (current._parent != null && currentParent == null)
                {
                    ((Visual3D)current._parent).SetFlagsToRoot(value, flag);
                    return;
                }

                current = currentParent;
            }
            while (current != null);
        }
Example #22
0
        /// <summary>
        /// Propagates the flags up to the root.
        /// </summary>
        /// <remarks>
        /// The walk stops on a node with all of the required flags set.
        /// </remarks>
        internal static void PropagateFlags(
            Visual3D e, 
            VisualFlags flags,
            VisualProxyFlags proxyFlags)
        {
            while ((e != null) && 
                   (!e.CheckFlagsAnd(flags) || !e.CheckFlagsOnAllChannels(proxyFlags)))
            {
                // These asserts are mostly for documentation when diffing the 2D/3D
                // implementations.
                Debug.Assert(!e.CheckFlagsOr(VisualFlags.ShouldPostRender),
                    "Visual3Ds should never be the root of a tree.");
                 Debug.Assert(!e.CheckFlagsOr(VisualFlags.NodeIsCyclicBrushRoot),
                    "Visual3Ds should never be the root of an ICyclicBrush.");

                e.SetFlags(true, flags);
                e.SetFlagsOnAllChannels(true, proxyFlags);

                // If our 3D parent is null call back into VisualTreeUtils to potentially
                // continue the walk in 2D.
                if (e._3DParent == null)
                {
                    Viewport3DVisual viewport = e.InternalVisualParent as Viewport3DVisual;

                    Debug.Assert((viewport == null) == (e.InternalVisualParent == null),
                        "Viewport3DVisual is the only supported 2D parent of a 3D visual.");
                    
                    if(viewport != null)
                    {
                        // We must notify the 2D visual that its contents have changed.
                        // This will cause the 2D visual to set it's content dirty flag
                        // and continue the propagation of IsDirtyForRender/Precompute.
                        viewport.Visual3DTreeChanged();

                        // continue propagating flags up the 2D world
                        Visual.PropagateFlags(viewport, flags, proxyFlags);
                    }
                        
                    // Stop propagating.  We are at the root of the 3D subtree.
                    return;
                }

                e = e._3DParent;
            }
        }
Example #23
0
        /// <summary>
        ///     Finds the first ancestor of the given element which has the given
        ///     flags set.
        /// </summary>
        internal DependencyObject FindFirstAncestorWithFlagsAnd(VisualFlags flag)
        {
            Visual current = this;

            do
            {
                if (current.CheckFlagsAnd(flag))
                {
                    // The other Visual crossed through this Visual's parent chain. Hence this is our
                    // common ancestor.
                    return current;
                }

                DependencyObject parent = current._parent;

                // first attempt to see if parent is a Visual, in which case we continue the loop.  
                // Otherwise see if it's a Visual3D, and call the similar method on it.
                current = parent as Visual;
                if (current == null)
                {
                    Visual3D parentAsVisual3D = parent as Visual3D;
                    if (parentAsVisual3D != null)
                    {
                        return parentAsVisual3D.FindFirstAncestorWithFlagsAnd(flag);
                    }
                }
            }
            while (current != null);

            return null;
        }