Exemple #1
0
        /// <summary>
        /// Gets the realized <see cref="Visual"/> associated with an item if the <see cref="Visual"/> has been realized already.
        /// </summary>
        /// <param name="item">The item associated with the returned <see cref="Visual"/>.</param>
        /// <returns>The <see cref="Visual"/> created in response to <see cref="RealizeItem"/> with the given item, or null if none has been created.</returns>
        public Visual VisualFromItem(ISpatialItem item)
        {
            Visual visual = null;

            this.visualMap.TryGetValue(item, out visual);
            return(visual);
        }
Exemple #2
0
        /// <summary>
        /// RealizeItems from the itemsToRealize enumerable upto the maxItemsToRealize limit.
        /// </summary>
        /// <param name="itemsToRealize">items to realize</param>
        /// <param name="realizedItems">Set of Realized Items</param>
        /// <param name="maxItemsToRealize">Max limit of items to realize</param>
        /// <returns>count of items realized.</returns>
        private int RealizeItems(IEnumerator <ISpatialItem> itemsToRealize, HashSet <ISpatialItem> realizedItems, int maxItemsToRealize)
        {
            int itemsRealized = 0;

            // This has to happen again because of the lazy throttling that can happen after RealizeOverride has returned.
            IVisualFactory f = VisualFactory ?? this.defaultFactory;

            f.BeginRealize();

            // Realize n items where n <= this.realizationQuantum.
            while (itemsRealized < maxItemsToRealize && itemsToRealize.MoveNext())
            {
                ISpatialItem item           = itemsToRealize.Current;
                Visual       realizedVisual = RealizeItem(item, false);

                if (realizedVisual != null)
                {
                    itemsRealized++;
                    realizedItems.Add(item);
                }
            }

            f.EndRealize();

            return(itemsRealized);
        }
Exemple #3
0
        /// <summary>
        /// Forces the item to be virtualized.
        /// </summary>
        public void ForceVirtualizeItem(ISpatialItem item)
        {
            Visual visual = VisualFromItem(item);

            if (visual != null)
            {
                ForceVirtualizeItem(item, visual);
            }
        }
Exemple #4
0
        private void ForceVirtualizeItem(ISpatialItem item, Visual visual)
        {
            this.visualChildren.Remove(visual);
            RemoveVisualChild(visual);
            this.visualMap.Remove(item);
            visual.ClearValue(RealizedItemPropertyKey);

            // This kills performance of scrolling and zooming because it adds a ton of extra cleanup work.
            // But we don't know why it was added yet, so we'll see what breaks when we remove it.
            // visual.ClearValue(FrameworkElement.DataContextProperty);
            itemsRemoved++;
        }
Exemple #5
0
        /// <summary>
        /// Destroys and/or recycles a visual from an item and removes it as a visual child.
        /// </summary>
        /// <param name="item">The item to remove the visual for.</param>
        private void VirtualizeItem(ISpatialItem item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            Visual visual;

            if (this.visualMap.TryGetValue(item, out visual))
            {
                if (this.ShouldVirtualize(item))
                {
                    this.ForceVirtualizeItem(item, visual);
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Arranges the content of a <see cref="VirtualCanvas"/> element.
        /// </summary>
        /// <param name="finalSize">The size that this <see cref="VirtualCanvas"/> element should use to arrange its child elements.</param>
        /// <returns>A <see cref="Size"/> that represents the arranged size of this <see cref="VirtualCanvas"/> element and its descendants.</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            using (this.BeginUpdate())
            {
                try
                {
                    if (Measuring != null)
                    {
                        Measuring(this, EventArgs.Empty);
                    }
                    doingLayout = true;

                    foreach (Visual visual in this.VisualChildren)
                    {
                        UIElement child = visual as UIElement;
                        if (child != null)
                        {
                            ISpatialItem spatialItem   = (ISpatialItem)ItemFromVisual(child);
                            Rect         desiredBounds = new Rect(spatialItem.Bounds.TopLeft, child.DesiredSize);
                            desiredBounds.X      = desiredBounds.X.AtLeast(Single.MinValue / 2);
                            desiredBounds.Y      = desiredBounds.Y.AtLeast(Single.MinValue / 2);
                            desiredBounds.Width  = desiredBounds.Width.AtMost(Single.MaxValue);
                            desiredBounds.Height = desiredBounds.Height.AtMost(Single.MaxValue);
                            child.Arrange(desiredBounds);
                            child.RaiseEvent(new RoutedEventArgs(FrameworkElement.SizeChangedEvent));

                            ZoomWatcher.TickleZoomable(this.Scale, child);
                        }
                    }

                    if (Measured != null)
                    {
                        Measured(this, EventArgs.Empty);
                    }
                }
                finally
                {
                    doingLayout = false;
                }
                return(finalSize);
            }
        }
Exemple #7
0
        /// <summary>
        /// Determines if the item should be virtualized.
        /// </summary>
        /// <returns>True if the item should be virtualized.</returns>
        private bool ShouldVirtualize(ISpatialItem item)
        {
            if (this.Items == null || !item.IsVisible)
            {
                return(true);
            }

            UIElement visual = VisualFromItem(item) as UIElement;

            if (visual == null)
            {
                return(true);
            }
            else if (visual.IsMouseCaptureWithin || visual.IsKeyboardFocusWithin || visual.IsFocused)
            {
                return(false);
            }

            return(VisualFactory == null || VisualFactory.Virtualize(visual));
        }
Exemple #8
0
        /// <summary>
        /// Measures the child elements of a <see cref="VirtualCanvas"/> in anticipation of arranging them during the <see cref="ArrangeOverride"/> pass.
        /// </summary>
        /// <param name="availableSize">An upper limit <see cref="Size"/> that should not be exceeded.</param>
        /// <returns>A <see cref="Size"/> that represents the size that is required to arrange child content.</returns>
        protected override Size MeasureOverride(Size availableSize)
        {
            Size finalSize = new Size();

            doingLayout = true;
            try
            {
                if (Measuring != null)
                {
                    Measuring(this, EventArgs.Empty);
                }

                // Currently we are only enumerating actual visuals to get the extent that SizeToContent sizes to.
                // We may want to think about changing the definition of SizeToContent to account for virtualized items too.
                foreach (Visual visual in this.VisualChildren)
                {
                    UIElement child = visual as UIElement;
                    if (child != null)
                    {
                        // Initialize child constraint to infinity.  We need to get a "natural" size for the child in absence of constraint.
                        Size infiniteConstraint = new Size(Double.PositiveInfinity, Double.PositiveInfinity);
                        child.Measure(infiniteConstraint);

                        ISpatialItem spatial = ItemFromVisual(child) as ISpatialItem;
                        if (spatial != null && this.ComputeOutlineGeometry)
                        {
                            spatial.OnMeasure(child);
                        }
                    }
                }
                if (Measured != null)
                {
                    Measured(this, EventArgs.Empty);
                }
            }
            finally
            {
                doingLayout = false;
            }
            return(finalSize);
        }
 private void HandleLeftButtonUp(IPointerEventArgs e)
 {
     if (m_Pointer != null)
     {
         ISpatialDocument doc = Scene?.Document;
         if (doc != null)
         {
             m_Hits.Clear();
             Coordinate pos = Scene.ViewToWorld(m_Position);
             doc.HitTest(pos.X, pos.Y, 5, 1 / Scene.Scale,
                         m_HitTestSpec, m_Hits);
             bool multi = e.KeyModifiers.HasFlag(KeyModifiers.Shift);
             if (m_Hits.Count == 1)
             {
                 if (!multi)
                 {
                     doc.DeselectAll();
                 }
                 var          pair  = m_Hits.First();
                 IItemsLayer  layer = pair.Value;
                 ISpatialItem item  = pair.Key;
                 if (layer.IsItemSelected(item))
                 {
                     if (multi)
                     {
                         layer.DeselectItem(item);
                     }
                 }
                 else
                 {
                     layer.SelectItem(item);
                 }
             }
             else
             {
                 doc.DeselectAll();
             }
         }
     }
 }
Exemple #10
0
 /// <summary>
 /// Determines if the item should be realized.
 /// </summary>
 /// <returns>True if the item should be realized.</returns>
 internal static bool ShouldRealize(ISpatialItem item)
 {
     return(item.IsVisible);
 }
Exemple #11
0
        /// <summary>
        /// Creates a <see cref="Visual"/> for an item and adds it as a visual child.
        /// </summary>
        /// <param name="item">The item to create a visual for.</param>
        /// <param name="force">Whether to tell the factory to force construction of this shape</param>
        /// <returns>The <see cref="Visual"/> created for the item.</returns>
        internal Visual RealizeItem(ISpatialItem item, bool force)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            if (!ShouldRealize(item))
            {
                return(null);
            }

            Visual visual;

            if (!this.visualMap.TryGetValue(item, out visual))
            {
                var    f        = VisualFactory;
                object dataItem = item.DataItem;
                visual = f.Realize(dataItem, force);
                if (visual != null)
                {
                    visual.SetValue(RealizedItemPropertyKey, item);
                    this.visualChildren.Add(visual, item.ZIndex);
                    AddVisualChild(visual);
                    // Set the data context after visual has been added to the tree so that the
                    // visual DataContextChanged event handler can find resources and other things
                    // that are inherited up the UI element hierarchy.
                    var element = visual as FrameworkElement;
                    if (element != null)
                    {
                        element.DataContext = dataItem;
                    }
                    this.visualMap.Add(item, visual);
                    itemsAdded++;
                    InvalidateMeasure();
                    InvalidateArrange();
                    if (visual is FrameworkElement e)
                    {
                        e.InvalidateVisual();
                    }
                }
            }
            else
            {
                bool updated = this.visualChildren.Update(visual, item.ZIndex);
                if (updated)
                {
                    itemsChanged++;
                    // this is the only way we can find to force WPF to redraw everything in the right order.
                    // Somehow, InvalidateVisual is not enough.
                    SetChangingZIndex(visual, true);
                    try
                    {
                        this.RemoveVisualChild(visual);
                        this.AddVisualChild(visual);
                    }
                    finally
                    {
                        visual.ClearValue(ChangingZIndexProperty);
                    }
                }
            }
            return(visual);
        }
Exemple #12
0
 /// <summary>
 /// Creates a <see cref="Visual"/> for an item and adds it as a visual child.
 /// </summary>
 /// <param name="item">The item to create a visual for.</param>
 /// <returns>The <see cref="Visual"/> created for the item.</returns>
 public Visual RealizeItem(ISpatialItem item)
 {
     return(RealizeItem(item, true));
 }