private static void SnapToLowGridLine(OhlcDataPoint point)
        {
            if (point.numericalPlot.SnapBaseTickIndex == -1 ||
                point.numericalPlot.SnapBaseTickIndex >= point.numericalPlot.Axis.ticks.Count)
            {
                return;
            }

            var baseTick = point.numericalPlot.Axis.ticks[point.numericalPlot.SnapBaseTickIndex];

            if (!RadMath.AreClose(point.numericalPlot.NormalizedLow, (double)baseTick.normalizedValue))
            {
                return;
            }

            var    tickRect = baseTick.layoutSlot;
            double gridLine = tickRect.Y + (int)(tickRect.Height / 2);

            double difference = gridLine - point.layoutSlot.Bottom;

            point.layoutSlot.Height += difference;

            if (point.layoutSlot.Height < 0)
            {
                point.layoutSlot.Height = 0;
            }
        }
Beispiel #2
0
        internal override IEnumerable <AxisTickModel> GenerateTicks(ValueRange <decimal> currentVisibleRange)
        {
            if (this.majorStep <= 0 || this.actualRange.maximum == this.actualRange.minimum)
            {
                yield break;
            }

            decimal tickStep           = (decimal)this.majorStep;
            decimal normalizedTickStep = tickStep / 360;

            decimal startTick   = 0;
            decimal endTick     = 1;
            decimal currentTick = startTick;
            decimal value       = 0;

            while (currentTick < endTick || RadMath.AreClose((double)currentTick, (double)endTick))
            {
                AxisTickModel tick = new MajorTickModel();
                tick.normalizedValue = this.IsInverse ? 1 - currentTick : currentTick;
                tick.value           = value;
                currentTick         += normalizedTickStep;
                value += tickStep;

                yield return(tick);
            }
        }
Beispiel #3
0
        public void SnapPointToGridLine(RangeDataPoint point)
        {
            if (point.numericalPlot.SnapTickIndex >= 0 && point.numericalPlot.SnapTickIndex < point.numericalPlot.Axis.ticks.Count)
            {
                AxisTickModel highTick = point.numericalPlot.Axis.ticks[point.numericalPlot.SnapTickIndex];
                if (RadMath.AreClose(point.numericalPlot.NormalizedHigh, (double)highTick.normalizedValue))
                {
                    if (this.PlotDirection == AxisPlotDirection.Vertical)
                    {
                        SnapHighToVerticalGridLine(point, highTick.layoutSlot);
                    }
                    else
                    {
                        SnapHighToHorizontalGridLine(point, highTick.layoutSlot);
                    }
                }
            }

            if (point.numericalPlot.SnapBaseTickIndex >= 0 && point.numericalPlot.SnapBaseTickIndex < point.numericalPlot.Axis.ticks.Count)
            {
                AxisTickModel lowTick = point.numericalPlot.Axis.ticks[point.numericalPlot.SnapBaseTickIndex];
                if (RadMath.AreClose(point.numericalPlot.NormalizedLow, (double)lowTick.normalizedValue))
                {
                    if (this.PlotDirection == AxisPlotDirection.Vertical)
                    {
                        SnapLowToVerticalGridLine(point, lowTick.layoutSlot);
                    }
                    else
                    {
                        SnapLowToHorizontalGridLine(point, lowTick.layoutSlot);
                    }
                }
            }
        }
        internal virtual void CheckTopScrollableBounds()
        {
            double firstItemTop = this.GetRealizedItemsTop();

            bool isFirstItemRealized = this.owner.firstItemCache != null && this.owner.GetItemBefore(this.owner.firstItemCache.associatedDataItem) == null;

            if (firstItemTop != this.ScrollOffset)
            {
                if (isFirstItemRealized && !RadMath.AreClose(firstItemTop, 0, 0.01) || (firstItemTop < 0 && this.ScrollOffset < this.ViewportLength / 4))
                {
                    double currentScrollOffset = this.ScrollOffset;
                    double newOffset           = this.ScrollOffset - firstItemTop;
                    if (!RadMath.AreClose(newOffset, this.ScrollOffset, 0.01))
                    {
                        // if (newOffset < 0 || (firstItemTop < 0 && RadMath.AreClose(0, this.ScrollOffset, Epsilon)))
                        {
                            this.EnsureCorrectLayout();
                        }
                    }
                }
                else
                {
                    this.CheckResizeScrollableContentWhenAllItemsRealized();
                }
            }
        }
        private RadRect InflateCellDecorationVertically(RadRect layoutSlot, Border decoration)
        {
            if (decoration.BorderBrush == null)
            {
                return(layoutSlot);
            }

            if (layoutSlot.Y < this.dayNamesLineSlot.Bottom)
            {
                layoutSlot.Y      -= decoration.BorderThickness.Bottom;
                layoutSlot.Height += decoration.BorderThickness.Bottom;
            }
            else if (RadMath.AreClose(layoutSlot.Bottom, this.Owner.CalendarViewSize.Height))
            {
                layoutSlot.Y      -= decoration.BorderThickness.Top;
                layoutSlot.Height += decoration.BorderThickness.Top + decoration.BorderThickness.Bottom;
            }
            else
            {
                layoutSlot.Y -= decoration.BorderThickness.Top;

                if (this.Owner.HasHorizontalGridLines)
                {
                    layoutSlot.Height += decoration.BorderThickness.Top + decoration.BorderThickness.Bottom;
                }
                else
                {
                    layoutSlot.Height += decoration.BorderThickness.Top;
                }
            }

            return(layoutSlot);
        }
        private static void SnapToHighGridLine(OhlcDataPoint point)
        {
            if (point.numericalPlot.SnapTickIndex < 0 ||
                point.numericalPlot.SnapTickIndex >= point.numericalPlot.Axis.ticks.Count)
            {
                return;
            }

            var topTick = point.numericalPlot.Axis.ticks[point.numericalPlot.SnapTickIndex];

            if (!RadMath.AreClose(point.numericalPlot.NormalizedHigh, (double)topTick.normalizedValue))
            {
                return;
            }

            var    tickRect = topTick.layoutSlot;
            double gridLine = tickRect.Y + (int)(tickRect.Height / 2);

            double difference = point.layoutSlot.Y - gridLine;

            point.layoutSlot.Y      -= difference;
            point.layoutSlot.Height += difference;

            if (point.layoutSlot.Height < 0)
            {
                point.layoutSlot.Height = 0;
            }
        }
        internal virtual void CheckBottomScrollableBounds()
        {
            double lastItemBottom          = this.GetRealizedItemsBottom();
            double scrollableContentBottom = this.GetScrollableContentEnd();

            bool isLastItemRealized = this.owner.GetItemAfter(this.owner.lastItemCache.associatedDataItem) == null;

            if (!RadMath.AreClose(lastItemBottom, scrollableContentBottom) || !isLastItemRealized)
            {
                if (isLastItemRealized)
                {
                    double offset = lastItemBottom - scrollableContentBottom;
                    this.CorrectScrollableContentSize(offset);
                    this.owner.OnBottomEdgeCorrected();
                }
                else if (scrollableContentBottom < this.scrollableContentHeightAdjustment + this.ViewportLength)
                {
                    //     this.CorrectScrollableContentSize(this.scrollableItemsLength - this.ScrollableContentLength);
                    double amount = this.owner.GetDataItemCount() - Math.Max(this.owner.GetLastItemCacheIndex(), 0);
                    this.CorrectScrollableContentSize(amount * this.averageItemLength);
                }
                else
                {
                    this.CheckResizeScrollableContentWhenAllItemsRealized();
                }
            }

            //this.owner.previousScrollOffset = scrollOffset;
        }
        private RadRect InflateCellDecorationHorizontally(RadRect layoutSlot, Border decoration)
        {
            if (decoration.BorderBrush == null)
            {
                return(layoutSlot);
            }

            if (layoutSlot.X < this.weekNumbersLineSlot.Right)
            {
                layoutSlot.X     -= decoration.BorderThickness.Right;
                layoutSlot.Width += decoration.BorderThickness.Right;
            }
            else if (RadMath.AreClose(layoutSlot.Right, this.Owner.CalendarViewSize.Width))
            {
                layoutSlot.X     -= decoration.BorderThickness.Left;
                layoutSlot.Width += decoration.BorderThickness.Left + decoration.BorderThickness.Right;
            }
            else
            {
                layoutSlot.X -= decoration.BorderThickness.Left;

                if (this.Owner.HasVerticalGridLines)
                {
                    layoutSlot.Width += decoration.BorderThickness.Left + decoration.BorderThickness.Right;
                }
                else
                {
                    layoutSlot.Width += decoration.BorderThickness.Left;
                }
            }

            return(layoutSlot);
        }
 internal override void SetValueFromAxis(AxisModel axis, object newValue)
 {
     if (axis is NumericalAxisModel)
     {
         this.numericalPlot = newValue as NumericalAxisPlotInfo;
         if (this.numericalPlot != null)
         {
             this.isInNumericalRange = true;
             this.isPositive         = this.numericalPlot.NormalizedValue >= this.numericalPlot.NormalizedOrigin;
             //// inverse axis with negative point value is equivalent to regular axis with positive point value
             if (this.numericalPlot.Axis.IsInverse && !RadMath.AreClose(this.numericalPlot.NormalizedValue, this.numericalPlot.NormalizedOrigin))
             {
                 this.isPositive ^= true;
             }
         }
         else
         {
             this.isInNumericalRange = false;
             this.isPositive         = false;
         }
     }
     else if (axis is CategoricalAxisModel || axis is DateTimeContinuousAxisModel)
     {
         this.categoricalPlot      = newValue as CategoricalAxisPlotInfo;
         this.isInCategoricalRange = true;
     }
 }
        public void SnapPointToGridLine(CategoricalDataPoint point)
        {
            if (point.numericalPlot == null)
            {
                return;
            }

            if (point.numericalPlot.SnapTickIndex < 0 ||
                point.numericalPlot.SnapTickIndex >= point.numericalPlot.Axis.ticks.Count)
            {
                return;
            }

            AxisTickModel tick = point.numericalPlot.Axis.ticks[point.numericalPlot.SnapTickIndex];

            if (!RadMath.AreClose(point.numericalPlot.NormalizedValue, (double)tick.normalizedValue))
            {
                return;
            }

            if (this.PlotDirection == AxisPlotDirection.Vertical)
            {
                CategoricalSeriesRoundLayoutContext.SnapToGridLineVertical(point, tick.layoutSlot);
            }
            else
            {
                CategoricalSeriesRoundLayoutContext.SnapToGridLineHorizontal(point, tick.layoutSlot);
            }
        }
Beispiel #11
0
        internal override IEnumerable <AxisTickModel> GenerateTicks(ValueRange <decimal> currentVisibleRange)
        {
            // use the decimal type for higher accuracy; see the XML comments on the GetVisibleRange method
            decimal delta = (decimal)this.actualRange.maximum - (decimal)this.actualRange.minimum;

            if (delta <= 0)
            {
                yield break;
            }

            double scale = this.layoutStrategy.GetZoom();
            double step  = this.majorStep;

            if (scale != 1d)
            {
                step = NumericalAxisModel.NormalizeStep(step / scale);
            }

            decimal tickStep           = (decimal)step;
            decimal normalizedTickStep = tickStep / delta;

            currentVisibleRange.minimum -= currentVisibleRange.minimum % normalizedTickStep;
            currentVisibleRange.maximum += normalizedTickStep - (currentVisibleRange.maximum % normalizedTickStep);

            decimal startTick, endTick;

            if (this.IsInverse)
            {
                startTick = Math.Max(0, 1 - currentVisibleRange.maximum);
                endTick   = Math.Min(1, 1 - currentVisibleRange.minimum);
            }
            else
            {
                startTick = Math.Max(0, currentVisibleRange.minimum);
                endTick   = Math.Min(1, currentVisibleRange.maximum);
            }

            decimal currentTick = startTick;
            decimal value       = (decimal)this.actualRange.minimum + currentTick * delta;

            int virtualIndex = (int)((value - (decimal)this.actualRange.minimum) / tickStep);

            while (currentTick < endTick || RadMath.AreClose((double)currentTick, (double)endTick))
            {
                AxisTickModel tick = new MajorTickModel();
                tick.normalizedValue = this.IsInverse ? 1 - currentTick : currentTick;
                tick.value           = (decimal)this.ReverseTransformValue((double)value);
                tick.virtualIndex    = virtualIndex;

                currentTick += normalizedTickStep;
                value       += tickStep;
                virtualIndex++;

                yield return(tick);
            }
        }
        internal virtual void CheckTopScrollableBounds()
        {
            double firstItemTop         = this.GetRealizedItemsTop();
            double scrollableContentTop = -this.ScrollOffset;

            bool isFirstItemRealized = this.owner.GetItemBefore(this.owner.firstItemCache.associatedDataItem) == null;

            if (firstItemTop != scrollableContentTop)
            {
                if (isFirstItemRealized && firstItemTop > scrollableContentTop)
                {
                    double currentScrollOffset = -scrollableContentTop;
                    double offset    = firstItemTop - scrollableContentTop;
                    double newOffset = currentScrollOffset - offset;
                    if (!RadMath.AreClose(newOffset, this.ScrollOffset, Epsilon))
                    {
                        this.ScrollToOffset(newOffset, null);
                    }
                }
                else if (isFirstItemRealized && firstItemTop < scrollableContentTop)
                {
                    double amount = this.GetElementCanvasOffset(this.owner.itemsPanel) + (scrollableContentTop - firstItemTop);
                    this.SetElementCanvasOffset(this.owner.itemsPanel, amount);
                    double newScrollOffset  = this.ScrollOffset + (scrollableContentTop - firstItemTop);
                    double heightCorrection = Math.Max(0, newScrollOffset - this.ScrollableLength);
                    if (heightCorrection > 0)
                    {
                        this.CorrectScrollableContentSize(heightCorrection);
                    }
                    //     this.ScrollToOffset(Math.Min(newScrollOffset, this.ScrollableLength), null);
                }
                else if (scrollableContentTop > -this.scrollableContentHeightAdjustment)
                {
                    double currentScrollOffset = -scrollableContentTop;
                    double adjustment          = Math.Max(this.owner.GetFirstItemCacheIndex(), 1) * this.averageItemLength;
                    double newOffset           = currentScrollOffset + adjustment;
                    double heightCorrection    = Math.Max(0, newOffset - this.ScrollableLength);
                    if (heightCorrection > 0)
                    {
                        this.CorrectScrollableContentSize(heightCorrection);
                    }
                    newOffset = Math.Min(newOffset, this.ScrollableLength);
                    //this.ScrollToOffset(newOffset, () =>
                    //{
                    //    double correction = newOffset - this.ScrollOffset;
                    //    double amount = this.GetElementCanvasOffset(this.owner.itemsPanel) + adjustment - correction;
                    //    this.SetElementCanvasOffset(this.owner.itemsPanel, amount);
                    //});
                }
                else
                {
                    this.CheckResizeScrollableContentWhenAllItemsRealized();
                }
            }
        }
Beispiel #13
0
        private bool TryTranslateItemsPanelWithPullToRefreshHeight()
        {
            var currentOffset = this.virtualizationStrategy.GetElementCanvasOffset(this.itemsPanel);

            if (RadMath.AreClose(currentOffset, 0))
            {
                var length = this.virtualizationStrategy.LayoutOrientation == Orientation.Vertical ? this.pullToRefreshIndicator.DesiredSize.Height : this.pullToRefreshIndicator.DesiredSize.Width;

                this.TranslateItemsPanel(length);

                return(true);
            }

            return(false);
        }
        internal virtual void CheckBottomScrollableBounds()
        {
            if (this.owner.RealizedItems.Length == 0)
            {
                return;
            }

            double lastItemBottom          = this.GetRealizedItemsBottom();
            double scrollableContentBottom = this.GetScrollableContentEnd();

            bool isFirstItemRealized = this.owner.GetItemBefore(this.owner.firstItemCache.associatedDataItem) == null;
            bool isLastItemRealized  = this.owner.GetItemAfter(this.owner.lastItemCache.associatedDataItem) == null;

            if (!RadMath.AreClose(lastItemBottom, scrollableContentBottom) || !isLastItemRealized)
            {
                if (isLastItemRealized)
                {
                    double offsetChange  = lastItemBottom - scrollableContentBottom;
                    var    lastItemEnd   = lastItemBottom;
                    var    lastItemStart = this.owner.lastItemCache.CurrentOffset;

                    if (lastItemEnd < this.ScrollOffset + this.ViewportLength && offsetChange < 0 || lastItemStart < this.ScrollOffset + this.ViewportLength || this.ScrollOffset + this.ViewportLength > this.ScrollableLength)
                    {
                        if (!RadMath.AreClose(offsetChange, 0, 0.1))
                        {
                            this.CorrectScrollableContentSize(offsetChange);
                            this.owner.OnBottomEdgeCorrected();
                        }
                    }
                }
                else if (!RadMath.AreClose(lastItemBottom, scrollableContentBottom) && !(isFirstItemRealized && isLastItemRealized))
                {
                    var estimatedLength = this.scrollableItemsLength;

                    var change = estimatedLength - scrollableContentBottom;

                    if (Math.Abs(change) > 0.01)
                    {
                        this.CorrectScrollableContentSize(change);
                    }
                }
                else if (isFirstItemRealized && isLastItemRealized)
                {
                    this.CheckResizeScrollableContentWhenAllItemsRealized();
                }
            }
        }
        internal override IEnumerable <AxisTickModel> GenerateTicks(ValueRange <decimal> currentVisibleRange)
        {
            int categoryCount = this.categories.Count;

            if (categoryCount == 0)
            {
                yield break;
            }

            int tickInterval   = this.GetMajorTickInterval();
            int emptyTickCount = 0;

            int     tickCount          = categoryCount;
            decimal tickStep           = tickCount == 1 ? 1 : 1m / tickCount;
            decimal normalizedTickStep = tickStep * 360;

            decimal startTick   = 0;
            decimal endTick     = 1 - tickStep;
            decimal currentTick = startTick;
            decimal value       = 0;

            int virtualIndex = (int)(startTick / tickStep);

            while (currentTick < endTick || RadMath.AreClose((double)currentTick, (double)endTick))
            {
                if (emptyTickCount == 0)
                {
                    AxisTickModel tick = new MajorTickModel();
                    tick.normalizedValue = this.IsInverse ? 1 - currentTick : currentTick;
                    tick.value           = value;
                    tick.virtualIndex    = virtualIndex;

                    emptyTickCount = tickInterval - 1;

                    yield return(tick);
                }
                else
                {
                    emptyTickCount--;
                }

                currentTick += tickStep;
                value       += normalizedTickStep;
                virtualIndex++;
            }
        }
Beispiel #16
0
        private void ArrangePolarLines()
        {
            // update polar (radius) lines
            int polarLinesIndex = 0;

            if ((this.linesVisibility & PolarGridLineVisibility.Polar) == PolarGridLineVisibility.Polar)
            {
                double antiAliasOffset = -1;

                foreach (RadPolarVector vector in this.model.polarLines)
                {
                    Line line = this.GetLineVisual(polarLinesIndex);
                    line.X1 = vector.Center.X;
                    line.Y1 = vector.Center.Y;
                    line.X2 = vector.Point.X;
                    line.Y2 = vector.Point.Y;

                    if (antiAliasOffset == -1)
                    {
                        antiAliasOffset = line.StrokeThickness % 2 == 1 ? 0.5 : 0;
                    }

                    if (RadMath.AreClose(line.Y1, line.Y2))
                    {
                        line.Y1 -= antiAliasOffset;
                        line.Y2 -= antiAliasOffset;
                    }
                    else if (RadMath.AreClose(line.X1, line.X2))
                    {
                        line.X1 += antiAliasOffset;
                        line.X2 += antiAliasOffset;
                    }

                    polarLinesIndex++;
                }
            }

            // hide not used lines
            while (polarLinesIndex < this.polarLines.Count)
            {
                this.polarLines[polarLinesIndex].Visibility = Visibility.Collapsed;
                polarLinesIndex++;
            }
        }
        private static void SnapToCloseGridLine(OhlcDataPoint point)
        {
            if (point.numericalPlot.SnapCloseTickIndex == -1 ||
                point.numericalPlot.SnapCloseTickIndex >= point.numericalPlot.Axis.ticks.Count)
            {
                return;
            }

            var closeTick = point.numericalPlot.Axis.ticks[point.numericalPlot.SnapCloseTickIndex];

            if (!RadMath.AreClose(point.numericalPlot.NormalizedClose, (double)closeTick.normalizedValue))
            {
                return;
            }

            var    tickRect = closeTick.layoutSlot;
            double gridLine = tickRect.Y + (int)(tickRect.Height / 2);

            point.numericalPlot.PhysicalClose = gridLine - point.layoutSlot.Y;
        }
Beispiel #18
0
        internal override IEnumerable <AxisTickModel> GenerateTicks(ValueRange <decimal> currentVisibleRange)
        {
            if (!this.CanPlot || !(this.plotInfo.Min < this.plotInfo.Max))
            {
                yield break;
            }

            this.UpdateVisibleTicks(currentVisibleRange);
            decimal plotDelta = this.plotInfo.Max - this.plotInfo.Min;

            decimal startTicks         = Math.Max(0, (this.visibleTicks.minimum - this.plotInfo.Min) / plotDelta);
            decimal endTicks           = Math.Min(1, (this.visibleTicks.maximum - this.plotInfo.Min) / plotDelta);
            decimal currentTicks       = startTicks;
            decimal paddedCurrentTicks = currentTicks;

            int virtualIndex = (int)(startTicks * this.values.Count);

            if (this.actualPlotMode == AxisPlotMode.OnTicksPadded)
            {
                decimal nextTicks = this.GetNextTicks(this.plotInfo.Min, this.tickZoomFactor);
                paddedCurrentTicks += (nextTicks - this.plotInfo.Min) / plotDelta / 2;
            }

            while (paddedCurrentTicks < endTicks || RadMath.AreClose((double)paddedCurrentTicks, (double)endTicks))
            {
                MajorTickModel tick = new MajorTickModel();
                tick.virtualIndex    = virtualIndex;
                tick.normalizedValue = this.IsInverse ? 1 - paddedCurrentTicks : paddedCurrentTicks;
                tick.value           = this.plotInfo.Min + (currentTicks * plotDelta);

                decimal nextTicks = this.GetNextTicks(tick.value, this.tickZoomFactor);
                decimal step      = (nextTicks - tick.value) / plotDelta;
                currentTicks       += step;
                paddedCurrentTicks += step;
                virtualIndex++;

                yield return(tick);
            }
        }
Beispiel #19
0
        internal override IEnumerable <AxisTickModel> GenerateTicks(ValueRange <decimal> currentVisibleRange)
        {
            // use the decimal type for higher accuracy; see the XML comments on the GetVisibleRange method
            int categoryCount = this.categories.Count;

            if (categoryCount == 0)
            {
                yield break;
            }

            int tickInterval   = this.GetMajorTickInterval();
            int emptyTickCount = 0;

            int     tickCount = this.actualPlotMode == AxisPlotMode.OnTicks ? categoryCount : categoryCount + 1;
            decimal tickStep  = tickCount == 1 ? 1 : 1m / (tickCount - 1);

            currentVisibleRange.minimum -= currentVisibleRange.minimum % tickStep;
            currentVisibleRange.maximum += tickStep - (currentVisibleRange.maximum % tickStep);
            decimal startTick, endTick;

            if (this.IsInverse)
            {
                startTick = Math.Max(0, 1 - currentVisibleRange.maximum);
                endTick   = Math.Min(1, 1 - currentVisibleRange.minimum);
            }
            else
            {
                startTick = Math.Max(0, currentVisibleRange.minimum);
                endTick   = Math.Min(1, currentVisibleRange.maximum);
            }

            if (this.actualPlotMode == AxisPlotMode.OnTicksPadded)
            {
                startTick = tickStep / 2;
            }

            decimal currentTick = startTick;

            int virtualIndex = (int)(startTick / tickStep);

            while (currentTick < endTick || RadMath.AreClose((double)currentTick, (double)endTick))
            {
                if (emptyTickCount == 0)
                {
                    AxisTickModel tick = new MajorTickModel();
                    tick.normalizedValue = this.IsInverse ? 1 - currentTick : currentTick;
                    tick.value           = currentTick;
                    tick.virtualIndex    = virtualIndex;

                    emptyTickCount = tickInterval - 1;

                    yield return(tick);
                }
                else
                {
                    emptyTickCount--;
                }

                currentTick += tickStep;
                virtualIndex++;
            }
        }
        internal void GenerateFrozenContainers()
        {
            if (!this.EnableFrozenDecorators)
            {
                return;
            }

            foreach (var frozenDecorators in this.generatedFrozenContainers)
            {
                foreach (var frozenDecorator in frozenDecorators.Value)
                {
                    this.Generator.RecycleDecorator(frozenDecorator);
                }
            }
            this.generatedFrozenContainers.Clear();

            for (int i = 0; i < this.frozenDecoratorsToGenerate.Count; i++)
            {
                bool   realized      = false;
                var    itemInfo      = this.frozenDecoratorsToGenerate[i];
                double desiredLength = 0;

                // Get list with frozen decorators per slot (created if empty);
                var frozenDecorator = this.GetPreviouslyVisibleFrozenDecorator(itemInfo.Id);

                realized = frozenDecorator != null;

                // Recycle cells on this slot if container is Collasped/Expanded.
                if (realized && (frozenDecorator.ItemInfo.IsCollapsed != itemInfo.IsCollapsed))
                {
                    this.Generator.RecycleDecorator(frozenDecorator);
                    realized = false;
                }

                if (!realized)
                {
                    frozenDecorator = this.GenerateAndPrepareFrozenContainer(ref itemInfo);
                }

                if (this.generatedFrozenContainers.ContainsKey(itemInfo.Id))
                {
                    this.generatedFrozenContainers[itemInfo.Id].Add(frozenDecorator);
                }
                else
                {
                    this.generatedFrozenContainers[itemInfo.Id] = new List <GeneratedItemModel>();
                    this.generatedFrozenContainers[itemInfo.Id].Add(frozenDecorator);
                }


                if (!realized)
                {
                    this.Owner.Measure(frozenDecorator, new RadSize(Double.PositiveInfinity, Double.PositiveInfinity));

                    desiredLength = this.IsHorizontal ? frozenDecorator.DesiredSize.Width : frozenDecorator.DesiredSize.Height;
                }
                else
                {
                    desiredLength = this.IsHorizontal ? frozenDecorator.DesiredSize.Width : frozenDecorator.DesiredSize.Height;
                }

                //Workaround for the optimizations of the measure in cases where desiredsize is 0,0.
                desiredLength = RadMath.AreClose(desiredLength, 0) ? defaultGroupHeaderLength : desiredLength;

                this.frozenDecoratorLengthPerLevel[itemInfo.Level]     = desiredLength;
                this.generatedFrozenDecoratorsPerLevel[itemInfo.Level] = frozenDecorator;
            }

            this.frozenDecoratorsToGenerate.Clear();
        }
Beispiel #21
0
 private static bool GreaterThan(double value1, double value2)
 {
     return((value1 > value2) && !RadMath.AreClose(value1, value2));
 }
        private Rect FindFreeSpotForItemTop(RadVirtualizingDataControlItem item)
        {
            RadVirtualizingDataControlItem startingItem = item.next;

            Dictionary <double, Rect> slots = new Dictionary <double, Rect>();

            while (startingItem != null)
            {
                switch (this.orientationCache)
                {
                case Orientation.Horizontal:
                    if (!slots.ContainsKey(startingItem.horizontalOffsetCache))
                    {
                        slots.Add(startingItem.horizontalOffsetCache,
                                  new Rect(startingItem.horizontalOffsetCache, startingItem.verticalOffsetCache, startingItem.width, startingItem.height));
                    }
                    break;

                case Orientation.Vertical:
                    if (!slots.ContainsKey(startingItem.verticalOffsetCache))
                    {
                        slots.Add(startingItem.verticalOffsetCache,
                                  new Rect(startingItem.horizontalOffsetCache, startingItem.verticalOffsetCache, startingItem.width, startingItem.height));
                    }
                    break;
                }

                if (slots.Count == this.stackCount)
                {
                    break;
                }

                startingItem = startingItem.next;
            }

            Rect?slot = null;
            int  slotIndex;

            if (this.slotsRepository.TryGetValue(item.associatedDataItem.GetHashCode(), out slotIndex))
            {
                switch (this.orientationCache)
                {
                case Orientation.Horizontal:
                    Rect itemSlot = slots.Values.Where <Rect>(rect => RadMath.AreClose(rect.Left, slotIndex * this.itemExtent, Epsilon)).FirstOrDefault <Rect>();
                    return(new Rect(itemSlot.Left, itemSlot.Top - item.height, item.width, item.height));

                case Orientation.Vertical:
                    itemSlot = slots.Values.Where <Rect>(rect => RadMath.AreClose(rect.Top, slotIndex * this.itemExtent, Epsilon)).FirstOrDefault <Rect>();
                    return(new Rect(itemSlot.Left - item.width, itemSlot.Top, item.width, item.height));
                }
            }

            Rect[] sortedValues = new Rect[this.stackCount];

            Rect[] sorted = this.orientationCache == Orientation.Horizontal ? slots.Values.OrderByDescending <Rect, double>(r => r.Left).ToArray <Rect>() :
                            slots.Values.OrderByDescending <Rect, double>(r => r.Top).ToArray <Rect>();
            sorted.CopyTo(sortedValues, 0);
            if (sorted.Length < this.stackCount)
            {
                int difference = sorted.Length;
                for (int i = difference; i < this.stackCount; i++)
                {
                    switch (this.orientationCache)
                    {
                    case Orientation.Horizontal:
                        sortedValues[i] = new Rect(i * this.itemExtent, this.ScrollOffset + this.GetElementCanvasOffset(this.owner.itemsPanel), 0, 0);
                        break;

                    case Orientation.Vertical:
                        sortedValues[i] = new Rect(this.ScrollOffset + this.GetElementCanvasOffset(this.owner.itemsPanel), i * this.itemExtent, 0, 0);
                        break;
                    }
                }
            }

            foreach (Rect freeSlot in sortedValues)
            {
                switch (this.orientationCache)
                {
                case Orientation.Horizontal:
                    if (slot == null)
                    {
                        slot = freeSlot;
                        continue;
                    }
                    else
                    {
                        if (freeSlot.Top > slot.Value.Top)
                        {
                            slot = freeSlot;
                        }
                    }
                    break;

                case Orientation.Vertical:
                    if (slot == null)
                    {
                        slot = freeSlot;
                        continue;
                    }
                    else
                    {
                        if (freeSlot.Left > slot.Value.Left)
                        {
                            slot = freeSlot;
                        }
                    }
                    break;
                }
            }

            if (slot == null)
            {
                slot = new Rect();
            }
            else
            {
                Rect valueSlot = slot.Value;
                switch (this.orientationCache)
                {
                case Orientation.Horizontal:
                    slot = new Rect(valueSlot.Left, valueSlot.Top - item.height, item.width, item.height);
                    break;

                case Orientation.Vertical:
                    slot = new Rect(valueSlot.Left - item.width, valueSlot.Top, item.width, item.height);
                    break;
                }
            }

            return(slot.Value);
        }
 internal virtual bool IsViewportFilled(double visibleItemsBottom)
 {
     return(RadMath.AreClose(visibleItemsBottom, this.ViewportLength));
 }
Beispiel #24
0
        internal override void EnsureCorrectLayout()
        {
            if (this.owner.RealizedItems.Length == 0)
            {
                base.EnsureCorrectLayout();
                return;
            }

            bool isLayoutCorrect = true;

            var item = this.owner.firstItemCache;

            for (int i = 0; i < this.StackCount; i++)
            {
                if (item == null)
                {
                    return;
                }

                var rowIndex = item.AssociatedDataItem.Index / this.StackCount;

                if (rowIndex == 0)
                {
                    isLayoutCorrect = RadMath.AreClose(this.GetItemRelativeOffset(item), 0, 0.01);

                    if (!isLayoutCorrect)
                    {
                        break;
                    }
                }

                item = item.next;
            }

            var firstRealizedItem = this.GetTopVisibleContainer();

            if (firstRealizedItem == null)
            {
                return;
            }

            var startPosition = firstRealizedItem.CurrentOffset;

            var manipulationOffset = 0.0;

            if (this.owner != null && this.owner.manipulationContainer != null)
            {
                manipulationOffset = this.ScrollOffset;
            }

            if (!isLayoutCorrect ||
                (startPosition + manipulationOffset < 0 && manipulationOffset < this.averageItemLength))
            {
                //reposition all
                this.owner.firstItemCache = this.owner.realizedItems[0];
                var container = this.owner.firstItemCache;

                var size = 0.0;

                while (container != null)
                {
                    container.horizontalOffsetCache = 0;
                    container.verticalOffsetCache   = 0;
                    container = container.next;
                }

                container = this.owner.firstItemCache;

                while (container != null)
                {
                    this.PositionBottomRealizedItem(container, ref size);
                    container = container.next;
                }
            }
        }