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; } }
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); } }
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); } }
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(); } } }
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++; } }
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; }
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); } }
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(); }
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)); }
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; } } }