Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Core / CSharp / System / Windows / Media / VisualBrush.cs / 1 / VisualBrush.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: VisualBrush.cs // // Description: This file contains the implementation of VisualBrush. // The VisualBrush is a TileBrush which defines its tile content // by use of a Visual. // // History: // //--------------------------------------------------------------------------- using System; using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security; using System.Windows; using System.Windows.Media; using System.Windows.Media.Media3D; using System.Windows.Media.Animation; using System.Windows.Media.Composition; using System.Windows.Threading; using MS.Internal; namespace System.Windows.Media { ////// VisualBrush - This TileBrush defines its content as a Visual /// public sealed partial class VisualBrush : TileBrush { // registration token used to register the brush with the media context internal class VisualBrushRegisterToken: ICompositionTarget { public VisualBrushRegisterToken(VisualBrush vb) { Debug.Assert(vb != null); _vb = vb; } public void Dispose() {} public void Render(bool inResize, DUCE.Channel channel) { _vb.Render(channel); } void ICompositionTarget.AddRefOnChannel(DUCE.Channel channel, DUCE.Channel outOfBandChannel) {} void ICompositionTarget.ReleaseOnChannel(DUCE.Channel channel, DUCE.Channel outOfBandChannel) {} bool ICompositionTarget.VisualTreeContainsGraphness() { return true; } private VisualBrush _vb; } #region Constructors ////// Default constructor for VisualBrush. The resulting Brush has no content. /// public VisualBrush() { _vbToken = new VisualBrushRegisterToken(this); } ////// VisualBrush Constructor where the image is set to the parameter's value /// /// The Visual representing the contents of this Brush. public VisualBrush(Visual visual) { if (this.Dispatcher != null) { MediaSystem.AssertSameContext(this, visual); Visual = visual; } } #endregion Constructors ////// This node can introduce graphness /// internal override bool CanIntroduceGraphness() { return true; } internal void FireOnChanged() { // Simple loop detection to avoid stack overflow in cyclic VisualBrush // scenarios. This fix is only aimed at mitigating a very common // VisualBrush scenario. bool canEnter = Enter(); if (canEnter) { try { _isCacheDirty = true; FireChanged(); } finally { Exit(); } } } internal void Render(DUCE.Channel channel) { if (Visual != null) { RenderForVisualBrush(channel); } } internal VisualBrushRegisterToken BrushRegisterToken { get { if (_vbToken == null) { _vbToken = new VisualBrushRegisterToken(this); } return _vbToken; } } internal void RenderForVisualBrush( DUCE.Channel channel) { Visual vVisual = Visual; if (vVisual != null) { // ----------------------------------------------------------------------------------- // 1) Prepare the visual for rendering. // // Mark the node as is in a brush. This ensures that in the render // pass we initiate here, the node is forced to fully visible and // properly marshaled. vVisual.SetFlags(true, VisualFlags.NodeIsVisualBrushRoot); vVisual.Precompute(); // ----------------------------------------------------------------------------------- // 2) Prepare the render context. // RenderContext rc = new RenderContext(); rc.Initialize(channel, DUCE.ResourceHandle.Null); // ------------------------------------------------------------------------------------ // 3) Compile the scene. if (channel.IsConnected) { vVisual.Render(rc, 0); } else { // We can issue the release here instead of putting it in queue // since we are already in Render walk. ((DUCE.IResource)vVisual).ReleaseOnChannel(channel); } } } // Implement functions used to addref and release resources in codegen that need // to be specialized for Visual which doesn't implement DUCE.IResource internal void AddRefResource(Visual visual, DUCE.Channel channel) { if (visual != null) { visual.AddRefOnChannelForVisualBrush(this, channel); } } internal void ReleaseResource(Visual visual, DUCE.Channel channel) { if (visual != null) { visual.ReleaseOnChannelForVisualBrush(this, channel); } } ////// Implementation of protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.IsAValueChange || e.IsASubPropertyChange) { if ((e.Property == VisualProperty) || (e.Property == AutoLayoutContentProperty)) { // Should we initiate a layout on this Visual? // Yes, if AutoLayoutContent is true and if the Visual is a UIElement not already in // another tree (i.e. the parent is null) or its not the hwnd root. if (AutoLayoutContent) { Debug.Assert(!_pendingLayout); UIElement element = Visual as UIElement; if ((element != null) && ((VisualTreeHelper.GetParent(element) == null && !(element.IsRootElement)) || (VisualTreeHelper.GetParent(element) is Visual3D))) { // // We need 2 ways of initiating layout on the VisualBrush root. // 1. We add a handler such that when the layout is done for the // main tree and LayoutUpdated is fired, then we do layout for the // VisualBrush tree. // However, this can fail in the case where the main tree is composed // of just Visuals and never does layout nor fires LayoutUpdated. So // we also need the following approach. // 2. We do a BeginInvoke to start layout on the Visual. This approach // alone, also falls short in the scenario where if we are already in // MediaContext.DoWork() then we will do layout (for main tree), then look // at Loaded callbacks, then render, and then finally the Dispather will // fire us for layout. So during loaded callbacks we would not have done // layout on the VisualBrush tree. // // Depending upon which of the two layout passes comes first, we cancel // the other layout pass. // element.LayoutUpdated += OnLayoutUpdated; _DispatcherLayoutResult = Dispatcher.BeginInvoke( DispatcherPriority.Normal, new DispatcherOperationCallback(LayoutCallback), element); _pendingLayout = true; } } } } } ///DependencyObject.OnPropertyInvalidated . /// If the property is the Visual or the AutoLayoutContent property, we re-layout the Visual if /// possible. ////// We initiate the layout on the tree rooted at the Visual to which VisualBrush points. /// private void DoLayout(UIElement element) { Debug.Assert(element != null); DependencyObject parent = VisualTreeHelper.GetParent(element); if (!(element.IsRootElement) && (parent == null || parent is Visual3D)) { // // PropagateResumeLayout sets the LayoutSuspended flag to false if it were true. // UIElement.PropagateResumeLayout(null, element); element.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); element.Arrange(new Rect(element.DesiredSize)); } } ////// LayoutUpdate event handler. /// /// event sender (not used) /// event arguments (not used) private void OnLayoutUpdated(object sender, EventArgs args) { Debug.Assert(_pendingLayout); // Visual has to be a UIElement since the handler was added to it. UIElement element = (UIElement)Visual; Debug.Assert(element != null); // Unregister for the event element.LayoutUpdated -= OnLayoutUpdated; _pendingLayout = false; // // Since we are in this function that means that layoutUpdated fired before // Dispatcher.BeginInvoke fired. So we can abort the DispatcherOperation as // we will do the layout here. // Debug.Assert(_DispatcherLayoutResult != null); Debug.Assert(_DispatcherLayoutResult.Status == DispatcherOperationStatus.Pending); bool abortStatus = _DispatcherLayoutResult.Abort(); Debug.Assert(abortStatus); DoLayout(element); } ////// DispatcherOperation callback to initiate layout. /// /// The Visual root private object LayoutCallback(object arg) { Debug.Assert(_pendingLayout); UIElement element = arg as UIElement; Debug.Assert(element != null); // // Since we are in this function that means that Dispatcher.BeginInvoke fired // before LayoutUpdated fired. So we can remove the LayoutUpdated handler as // we will do the layout here. // element.LayoutUpdated -= OnLayoutUpdated; _pendingLayout = false; DoLayout(element); return null; } ////// Enter is used for simple cycle detection in VisualBrush. If the method returns false /// the brush has already been entered and cannot be entered again. Matching invocation of Exit /// must be skipped if Enter returns false. /// internal bool Enter() { if (_reentrancyFlag) { return false; } else { _reentrancyFlag = true; return true; } } ////// Exits the VisualBrush. For more details see Enter method. /// internal void Exit() { Debug.Assert(_reentrancyFlag); // Exit must be matched with Enter. See Enter comments. _reentrancyFlag = false; } ////// Obtains the current bounds of the brush's content /// /// Output bounds of content protected override void GetContentBounds(out Rect contentBounds) { // Obtain the current visual's outer space bounding box. We return the outer space // bounding box because we want to have the bounding box of the Visual tree including // transform/offset at the root. if (_isCacheDirty) { _bbox = Visual.CalculateSubgraphBoundsOuterSpace(); _isCacheDirty = false; } contentBounds = _bbox; } ////// Precompute is called during the frame preparation phase. Derived classes /// typically check if the brush requires realizations during this phase. /// internal override void Precompute() { Visual visual = Visual; if (visual != null) { // Simple loop detection to avoid stack overflow in cyclic VisualBrush // scenarios. This fix is only aimed at mitigating a very common // VisualBrush scenario. bool canEnter = Enter(); if (canEnter) { try { visual.Precompute(); _requiresRealizationUpdates = visual.RequiresRealizationUpdates; } finally { Exit(); } } } else { _requiresRealizationUpdates = false; } } ////// Checks if realization updates are requried for this resource. /// internal override bool RequiresRealizationUpdates { get { return _requiresRealizationUpdates; } } ////// Derived classes must override this method and update realizations on dependent /// resources if required. /// internal override void UpdateRealizations(Rect fillShapeBounds, RealizationContext ctx) { Visual visual = Visual; if (_requiresRealizationUpdates && (visual != null)) { // Simple loop detection to avoid stack overflow in cyclic VisualBrush // scenarios. This fix is only aimed at mitigating a very common // VisualBrush scenario. bool canEnter = Enter(); if (canEnter) { try { Matrix m; GetTileBrushMapping(fillShapeBounds, out m); ctx.TransformStack.Push(ref m, true); visual.MarkVisibleRealizations(ctx); ctx.TransformStack.Pop(); } finally { Exit(); } } } } internal VisualBrushRegisterToken _vbToken; private DispatcherOperation _DispatcherLayoutResult; private bool _pendingLayout; private bool _reentrancyFlag; private bool _requiresRealizationUpdates; // Whether we need to re-calculate our content bounds. private bool _isCacheDirty = true; // Keep our content bounds cached. private Rect _bbox = Rect.Empty; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: VisualBrush.cs // // Description: This file contains the implementation of VisualBrush. // The VisualBrush is a TileBrush which defines its tile content // by use of a Visual. // // History: // //--------------------------------------------------------------------------- using System; using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security; using System.Windows; using System.Windows.Media; using System.Windows.Media.Media3D; using System.Windows.Media.Animation; using System.Windows.Media.Composition; using System.Windows.Threading; using MS.Internal; namespace System.Windows.Media { ////// VisualBrush - This TileBrush defines its content as a Visual /// public sealed partial class VisualBrush : TileBrush { // registration token used to register the brush with the media context internal class VisualBrushRegisterToken: ICompositionTarget { public VisualBrushRegisterToken(VisualBrush vb) { Debug.Assert(vb != null); _vb = vb; } public void Dispose() {} public void Render(bool inResize, DUCE.Channel channel) { _vb.Render(channel); } void ICompositionTarget.AddRefOnChannel(DUCE.Channel channel, DUCE.Channel outOfBandChannel) {} void ICompositionTarget.ReleaseOnChannel(DUCE.Channel channel, DUCE.Channel outOfBandChannel) {} bool ICompositionTarget.VisualTreeContainsGraphness() { return true; } private VisualBrush _vb; } #region Constructors ////// Default constructor for VisualBrush. The resulting Brush has no content. /// public VisualBrush() { _vbToken = new VisualBrushRegisterToken(this); } ////// VisualBrush Constructor where the image is set to the parameter's value /// /// The Visual representing the contents of this Brush. public VisualBrush(Visual visual) { if (this.Dispatcher != null) { MediaSystem.AssertSameContext(this, visual); Visual = visual; } } #endregion Constructors ////// This node can introduce graphness /// internal override bool CanIntroduceGraphness() { return true; } internal void FireOnChanged() { // Simple loop detection to avoid stack overflow in cyclic VisualBrush // scenarios. This fix is only aimed at mitigating a very common // VisualBrush scenario. bool canEnter = Enter(); if (canEnter) { try { _isCacheDirty = true; FireChanged(); } finally { Exit(); } } } internal void Render(DUCE.Channel channel) { if (Visual != null) { RenderForVisualBrush(channel); } } internal VisualBrushRegisterToken BrushRegisterToken { get { if (_vbToken == null) { _vbToken = new VisualBrushRegisterToken(this); } return _vbToken; } } internal void RenderForVisualBrush( DUCE.Channel channel) { Visual vVisual = Visual; if (vVisual != null) { // ----------------------------------------------------------------------------------- // 1) Prepare the visual for rendering. // // Mark the node as is in a brush. This ensures that in the render // pass we initiate here, the node is forced to fully visible and // properly marshaled. vVisual.SetFlags(true, VisualFlags.NodeIsVisualBrushRoot); vVisual.Precompute(); // ----------------------------------------------------------------------------------- // 2) Prepare the render context. // RenderContext rc = new RenderContext(); rc.Initialize(channel, DUCE.ResourceHandle.Null); // ------------------------------------------------------------------------------------ // 3) Compile the scene. if (channel.IsConnected) { vVisual.Render(rc, 0); } else { // We can issue the release here instead of putting it in queue // since we are already in Render walk. ((DUCE.IResource)vVisual).ReleaseOnChannel(channel); } } } // Implement functions used to addref and release resources in codegen that need // to be specialized for Visual which doesn't implement DUCE.IResource internal void AddRefResource(Visual visual, DUCE.Channel channel) { if (visual != null) { visual.AddRefOnChannelForVisualBrush(this, channel); } } internal void ReleaseResource(Visual visual, DUCE.Channel channel) { if (visual != null) { visual.ReleaseOnChannelForVisualBrush(this, channel); } } ////// Implementation of protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.IsAValueChange || e.IsASubPropertyChange) { if ((e.Property == VisualProperty) || (e.Property == AutoLayoutContentProperty)) { // Should we initiate a layout on this Visual? // Yes, if AutoLayoutContent is true and if the Visual is a UIElement not already in // another tree (i.e. the parent is null) or its not the hwnd root. if (AutoLayoutContent) { Debug.Assert(!_pendingLayout); UIElement element = Visual as UIElement; if ((element != null) && ((VisualTreeHelper.GetParent(element) == null && !(element.IsRootElement)) || (VisualTreeHelper.GetParent(element) is Visual3D))) { // // We need 2 ways of initiating layout on the VisualBrush root. // 1. We add a handler such that when the layout is done for the // main tree and LayoutUpdated is fired, then we do layout for the // VisualBrush tree. // However, this can fail in the case where the main tree is composed // of just Visuals and never does layout nor fires LayoutUpdated. So // we also need the following approach. // 2. We do a BeginInvoke to start layout on the Visual. This approach // alone, also falls short in the scenario where if we are already in // MediaContext.DoWork() then we will do layout (for main tree), then look // at Loaded callbacks, then render, and then finally the Dispather will // fire us for layout. So during loaded callbacks we would not have done // layout on the VisualBrush tree. // // Depending upon which of the two layout passes comes first, we cancel // the other layout pass. // element.LayoutUpdated += OnLayoutUpdated; _DispatcherLayoutResult = Dispatcher.BeginInvoke( DispatcherPriority.Normal, new DispatcherOperationCallback(LayoutCallback), element); _pendingLayout = true; } } } } } ///DependencyObject.OnPropertyInvalidated . /// If the property is the Visual or the AutoLayoutContent property, we re-layout the Visual if /// possible. ////// We initiate the layout on the tree rooted at the Visual to which VisualBrush points. /// private void DoLayout(UIElement element) { Debug.Assert(element != null); DependencyObject parent = VisualTreeHelper.GetParent(element); if (!(element.IsRootElement) && (parent == null || parent is Visual3D)) { // // PropagateResumeLayout sets the LayoutSuspended flag to false if it were true. // UIElement.PropagateResumeLayout(null, element); element.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); element.Arrange(new Rect(element.DesiredSize)); } } ////// LayoutUpdate event handler. /// /// event sender (not used) /// event arguments (not used) private void OnLayoutUpdated(object sender, EventArgs args) { Debug.Assert(_pendingLayout); // Visual has to be a UIElement since the handler was added to it. UIElement element = (UIElement)Visual; Debug.Assert(element != null); // Unregister for the event element.LayoutUpdated -= OnLayoutUpdated; _pendingLayout = false; // // Since we are in this function that means that layoutUpdated fired before // Dispatcher.BeginInvoke fired. So we can abort the DispatcherOperation as // we will do the layout here. // Debug.Assert(_DispatcherLayoutResult != null); Debug.Assert(_DispatcherLayoutResult.Status == DispatcherOperationStatus.Pending); bool abortStatus = _DispatcherLayoutResult.Abort(); Debug.Assert(abortStatus); DoLayout(element); } ////// DispatcherOperation callback to initiate layout. /// /// The Visual root private object LayoutCallback(object arg) { Debug.Assert(_pendingLayout); UIElement element = arg as UIElement; Debug.Assert(element != null); // // Since we are in this function that means that Dispatcher.BeginInvoke fired // before LayoutUpdated fired. So we can remove the LayoutUpdated handler as // we will do the layout here. // element.LayoutUpdated -= OnLayoutUpdated; _pendingLayout = false; DoLayout(element); return null; } ////// Enter is used for simple cycle detection in VisualBrush. If the method returns false /// the brush has already been entered and cannot be entered again. Matching invocation of Exit /// must be skipped if Enter returns false. /// internal bool Enter() { if (_reentrancyFlag) { return false; } else { _reentrancyFlag = true; return true; } } ////// Exits the VisualBrush. For more details see Enter method. /// internal void Exit() { Debug.Assert(_reentrancyFlag); // Exit must be matched with Enter. See Enter comments. _reentrancyFlag = false; } ////// Obtains the current bounds of the brush's content /// /// Output bounds of content protected override void GetContentBounds(out Rect contentBounds) { // Obtain the current visual's outer space bounding box. We return the outer space // bounding box because we want to have the bounding box of the Visual tree including // transform/offset at the root. if (_isCacheDirty) { _bbox = Visual.CalculateSubgraphBoundsOuterSpace(); _isCacheDirty = false; } contentBounds = _bbox; } ////// Precompute is called during the frame preparation phase. Derived classes /// typically check if the brush requires realizations during this phase. /// internal override void Precompute() { Visual visual = Visual; if (visual != null) { // Simple loop detection to avoid stack overflow in cyclic VisualBrush // scenarios. This fix is only aimed at mitigating a very common // VisualBrush scenario. bool canEnter = Enter(); if (canEnter) { try { visual.Precompute(); _requiresRealizationUpdates = visual.RequiresRealizationUpdates; } finally { Exit(); } } } else { _requiresRealizationUpdates = false; } } ////// Checks if realization updates are requried for this resource. /// internal override bool RequiresRealizationUpdates { get { return _requiresRealizationUpdates; } } ////// Derived classes must override this method and update realizations on dependent /// resources if required. /// internal override void UpdateRealizations(Rect fillShapeBounds, RealizationContext ctx) { Visual visual = Visual; if (_requiresRealizationUpdates && (visual != null)) { // Simple loop detection to avoid stack overflow in cyclic VisualBrush // scenarios. This fix is only aimed at mitigating a very common // VisualBrush scenario. bool canEnter = Enter(); if (canEnter) { try { Matrix m; GetTileBrushMapping(fillShapeBounds, out m); ctx.TransformStack.Push(ref m, true); visual.MarkVisibleRealizations(ctx); ctx.TransformStack.Pop(); } finally { Exit(); } } } } internal VisualBrushRegisterToken _vbToken; private DispatcherOperation _DispatcherLayoutResult; private bool _pendingLayout; private bool _reentrancyFlag; private bool _requiresRealizationUpdates; // Whether we need to re-calculate our content bounds. private bool _isCacheDirty = true; // Keep our content bounds cached. private Rect _bbox = Rect.Empty; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SQLConvert.cs
- SynchronizationLockException.cs
- ParameterEditorUserControl.cs
- ValueOfAction.cs
- SoapBinding.cs
- Wizard.cs
- DirectoryInfo.cs
- SiteMembershipCondition.cs
- PropertyChangingEventArgs.cs
- CommentGlyph.cs
- WeakReadOnlyCollection.cs
- FrameworkObject.cs
- FileLogRecordStream.cs
- autovalidator.cs
- WebControl.cs
- RequiredAttributeAttribute.cs
- ResponseStream.cs
- ResXResourceReader.cs
- EncoderReplacementFallback.cs
- ColorBlend.cs
- StrokeNodeData.cs
- TypeCodeDomSerializer.cs
- HtmlTextArea.cs
- TableColumn.cs
- XmlSchemaSimpleContent.cs
- COM2AboutBoxPropertyDescriptor.cs
- ClientBase.cs
- ContextInformation.cs
- ContextMenu.cs
- TypeBinaryExpression.cs
- FixedSOMGroup.cs
- ReadOnlyDataSource.cs
- IDQuery.cs
- SafeCryptoHandles.cs
- FormViewUpdateEventArgs.cs
- EdgeProfileValidation.cs
- SQLMembershipProvider.cs
- XPathDescendantIterator.cs
- ProtectedConfiguration.cs
- ConfigXmlElement.cs
- ImageConverter.cs
- MappingMetadataHelper.cs
- BufferModeSettings.cs
- ConstNode.cs
- FontDriver.cs
- CircleEase.cs
- SiteMapNode.cs
- FastPropertyAccessor.cs
- FileSystemEventArgs.cs
- SizeConverter.cs
- KnownTypeDataContractResolver.cs
- XmlSerializerOperationGenerator.cs
- XsdCachingReader.cs
- Span.cs
- DecoderReplacementFallback.cs
- FilteredDataSetHelper.cs
- MenuCommandService.cs
- ProfilePropertySettings.cs
- AttachmentCollection.cs
- ProfileInfo.cs
- precedingquery.cs
- Bind.cs
- DbDataReader.cs
- TakeQueryOptionExpression.cs
- SerializerDescriptor.cs
- WebPartDescriptionCollection.cs
- baseaxisquery.cs
- CodeIdentifier.cs
- DynamicValidatorEventArgs.cs
- IdentityReference.cs
- SubtreeProcessor.cs
- DecimalAnimationBase.cs
- WebServiceData.cs
- ApplicationActivator.cs
- ServiceDescription.cs
- TableCell.cs
- DataViewSettingCollection.cs
- WmpBitmapEncoder.cs
- WebPageTraceListener.cs
- ArgumentException.cs
- AnimationClock.cs
- GeneralTransform.cs
- SqlFunctions.cs
- TextComposition.cs
- ModelEditingScope.cs
- TextDecoration.cs
- WebServiceTypeData.cs
- ResourceDisplayNameAttribute.cs
- SmtpMail.cs
- ApplicationActivator.cs
- HttpBufferlessInputStream.cs
- DataFieldConverter.cs
- SecurityTokenProvider.cs
- CommandEventArgs.cs
- LocalizationParserHooks.cs
- InputEventArgs.cs
- BufferedOutputAsyncStream.cs
- ObjectNavigationPropertyMapping.cs
- DataBoundControlAdapter.cs
- InputLanguage.cs