Exemplo n.º 1
0
        public ViewportInfo GetRelativeTo(IFrameworkElement_EffectiveViewport element)
        {
            Rect effective = Effective, clip = Clip;

            if (element is UIElement uiElement && Reference is UIElement usuallyTheParentOfElement)
            {
                var parentToElement = UIElement.GetTransform(uiElement, usuallyTheParentOfElement).Inverse();

                if (Effective.IsValid)
                {
                    effective = parentToElement.Transform(Effective);
                }

                if (Clip.IsValid)
                {
                    clip = parentToElement.Transform(Clip);
                }
            }

            // If the Reference or the element is not a UIElement (native), we don't have any RenderTransform,
            // and we assume that the 'element' is stretched in it's parent usually true except for ListView,
            // but we won't even try to support that case.

            return(new ViewportInfo(element, effective, clip));
        }
        /// <summary>
        /// Used by a parent element to propagate down the viewport change
        /// </summary>
        void IFrameworkElement_EffectiveViewport.OnParentViewportChanged(
            IFrameworkElement_EffectiveViewport parent, // We propagate the parent to avoid costly lookup
            Rect viewport,                              // Be aware tht it might be empty ([+∞,+∞,-∞,-∞]) if not clipped
            bool isInitial)                             // Indicates that this update is only intended to initiate the _parentViewport
        {
            if (!IsEffectiveViewportEnabled)
            {
                // We do not keep the _parentViewport up-to-date if not needed.
                // It's expected to the root parent to update its children when propagation activated.
                return;
            }

#if IS_NATIVE_ELEMENT // No RenderTransform on native elements
            var viewportInLocalCoordinates = viewport;
#else
            var viewportInLocalCoordinates = !viewport.IsEmpty && parent is UIElement parentElt
                                ? GetTransform(this, parentElt).Inverse().Transform(viewport)
                                : viewport;
#endif

            if (!isInitial && viewportInLocalCoordinates == _parentViewport)
            {
                return;
            }

            _parentViewport = viewportInLocalCoordinates;
            PropagateEffectiveViewportChange(isInitial);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Used by a child of this element, in order to subscribe to viewport updates
        /// (so the OnParentViewportChanged will be invoked on this given child)
        /// </summary>
        IDisposable IFrameworkElement_EffectiveViewport.RequestViewportUpdates(IFrameworkElement_EffectiveViewport child)
        {
            global::System.Diagnostics.Debug.Assert(Uno.UI.Extensions.DependencyObjectExtensions.GetChildren(this).OfType <IFrameworkElement_EffectiveViewport>().Contains(child));

            _childrenInterestedInViewportUpdates++;
            ReconfigureViewportPropagation(child);

            return(Disposable.Create(() =>
            {
                _childrenInterestedInViewportUpdates--;
                ReconfigureViewportPropagation();
            }));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Make sure to request or disable effective viewport changes from the parent
        /// </summary>
        private void ReconfigureViewportPropagation(IFrameworkElement_EffectiveViewport child = null)
        {
            if (IsLoaded && IsEffectiveViewportEnabled)
            {
                if (_parentViewportUpdatesSubscription == null)
                {
                    TRACE_EFFECTIVE_VIEWPORT("Enabling effective viewport propagation.");

                    var parent = this.GetVisualTreeParent();
                    if (parent is IFrameworkElement_EffectiveViewport parentFwElt)
                    {
                        _parentViewportUpdatesSubscription = parentFwElt.RequestViewportUpdates(this);
                    }
                    else
                    {
                        // We are the root of the visual tree (maybe just temporarily),
                        // we update the effective viewport in order to initialize the _parentViewport of children.
                        PropagateEffectiveViewportChange(isInitial: true);
                    }
                }
                else
                {
                    TRACE_EFFECTIVE_VIEWPORT("New child requested viewport propagation which has already been enabled. Force updating all children.");

                    // We are already subscribed, the parent won't send any update (and our _parentViewport is expected to be up-to-date).
                    // But if this "reconfigure" was made for a new child (child != null), we have to initialize its own _parentViewport.

                    var slot           = LayoutInformation.GetLayoutSlot(this);           // a.k.a. the implicit viewport to use if none was defined by any parent (usually only few elements at the top of the tree)
                    var parentViewport = GetParentViewport();
                    var viewport       = GetEffectiveViewport(parentViewport, slot);

                    child?.OnParentViewportChanged(this, viewport, isInitial: true);
                }
            }
            else
            {
                if (_parentViewportUpdatesSubscription != null)
                {
                    TRACE_EFFECTIVE_VIEWPORT("Disabling effective viewport propagation.");

                    _parentViewportUpdatesSubscription.Dispose();
                    _parentViewportUpdatesSubscription = null;

                    _parentViewport = Rect.Empty;
                }
            }
        }
Exemplo n.º 5
0
        void IFrameworkElement_EffectiveViewport.OnParentViewportChanged(
            bool isInitial,                             // Update is intended to initiate the _parentViewport and should be "public" only if not due to a new event listener while tree is live (e.g. load)
            bool isInternal,                            // Indicates that this update is due to a new event handler
            IFrameworkElement_EffectiveViewport parent, // We propagate the parent to avoid costly lookup
            ViewportInfo viewport)                      // The viewport of the parent, expressed in parent's coordinates
        {
            if (!IsEffectiveViewportEnabled)
            {
                // We do not keep the _parentViewport up-to-date if not needed.
                // It's expected to the root parent to update its children when propagation activated.
                return;
            }

            if (!isInitial && viewport == _parentViewport)
            {
                return;
            }

            _parentViewport = viewport;
            PropagateEffectiveViewportChange(isInitial, isInternal);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Used by a parent element to propagate down the viewport change
        /// </summary>
        void IFrameworkElement_EffectiveViewport.OnParentViewportChanged(
            IFrameworkElement_EffectiveViewport parent, // We propagate the parent to avoid costly lookup
            Rect viewport,                              // Be aware tht it might be empty ([+∞,+∞,-∞,-∞]) if not clipped
            bool isInitial)                             // Indicates that this update is only intended to initiate the _parentViewport
        {
            if (!IsEffectiveViewportEnabled)
            {
                // We do not keep the _parentViewport up-to-date if not needed.
                // It's expected to the root parent to update its children when propagation activated.
                return;
            }

#if !__IOS__ // cf. GetParentViewport
            viewport = ParentToLocalCoordinates(parent, viewport);
#endif

            if (!isInitial && viewport == _parentViewport)
            {
                return;
            }

            _parentViewport = viewport;
            PropagateEffectiveViewportChange(isInitial);
        }
        /// <summary>
        /// Make sure to request or disable effective viewport changes from the parent
        /// </summary>
        private void ReconfigureViewportPropagation(IFrameworkElement_EffectiveViewport child = null)
        {
            if (IsLoaded && IsEffectiveViewportEnabled)
            {
                if (_parentViewportUpdatesSubscription == null)
                {
                    var parent = Parent;
                    if (parent is IFrameworkElement_EffectiveViewport parentFwElt)
                    {
                        _parentViewportUpdatesSubscription = parentFwElt.RequestViewportUpdates(this);
                    }
                    else
                    {
                        // We are the root of the visual tree (maybe just temporarily),
                        // we update the effective viewport in order to initialize the _parentViewport of children.
                        PropagateEffectiveViewportChange(isInitial: true);
                    }
                }
                else
                {
                    // We are already subscribed, the parent won't send any update (and our _parentViewport is expected to be up-to-date).
                    // But if this "reconfigure" was made for a new child (child != null), we have to initialize its own _parentViewport.
                    child?.OnParentViewportChanged(this, GetEffectiveViewport(), isInitial: true);
                }
            }
            else
            {
                if (_parentViewportUpdatesSubscription != null)
                {
                    _parentViewportUpdatesSubscription.Dispose();
                    _parentViewportUpdatesSubscription = null;

                    _parentViewport = Rect.Empty;
                }
            }
        }
Exemplo n.º 8
0
 public ViewportInfo(IFrameworkElement_EffectiveViewport reference, Rect effective, Rect clip)
 {
     Reference = reference;
     Effective = effective;
     Clip      = clip;
 }
Exemplo n.º 9
0
 public ViewportInfo(IFrameworkElement_EffectiveViewport reference, Rect viewport)
 {
     Reference = reference;
     Effective = Clip = viewport;
 }