protected override void Update() { base.Update(); float currentScroll = scrollContainer.Current; if (currentScroll != lastKnownScroll) { lastKnownScroll = currentScroll; OptionsSection bestCandidate = null; float bestDistance = float.MaxValue; foreach (OptionsSection section in sections) { float distance = Math.Abs(scrollContainer.GetChildPosInContent(section) - currentScroll); if (distance < bestDistance) { bestDistance = distance; bestCandidate = section; } } var previous = sidebarButtons.SingleOrDefault(sb => sb.Selected); var next = sidebarButtons.SingleOrDefault(sb => sb.Section == bestCandidate); if (next != null) { next.Selected = true; } if (previous != null) { previous.Selected = false; } } }
private bool moveItemToTargetPosition(Lyric newLyric, Lyric oldLyric, int skippingRows) { var oldItem = getListItem(oldLyric); var newItem = getListItem(newLyric); // new item might been deleted. if (newItem == null) { return(false); } var spacing = newItem.Height * skippingRows; // do not scroll if position is smaller then spacing. var scrollPosition = ScrollContainer.GetChildPosInContent(newItem); if (scrollPosition < spacing) { return(false); } // do not scroll if position is too large and not able to move to target position. var itemHeight = newItem.Height + newItem.ExtendHeight; var contentHeight = ScrollContainer.ScrollContent.Height; var containerHeight = ScrollContainer.DrawHeight; if (contentHeight - scrollPosition + itemHeight < containerHeight - spacing) { return(false); } ScrollContainer.ScrollTo(scrollPosition - spacing + getOffsetPosition(newItem, oldItem)); return(true); DrawableLyricEditListItem getListItem(Lyric lyric) => ListContainer.Children.FirstOrDefault(x => x.Model == lyric) as DrawableLyricEditListItem; float getOffsetPosition(DrawableLyricEditListItem newItem, DrawableLyricEditListItem oldItem) { if (oldItem == null) { return(0); } var newItemPosition = ScrollContainer.GetChildPosInContent(newItem); var oldItemPosition = ScrollContainer.GetChildPosInContent(oldItem); if (oldItemPosition > scrollPosition) { return(0); } // if previous lyric is in front of current lyric row, due to extend in previous row has been removed. // it will cause offset from previous row extend. return(-newItem.ExtendHeight); } }
protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); float headerH = (ExpandableHeader?.LayoutSize.Y ?? 0) + (FixedHeader?.LayoutSize.Y ?? 0); float footerH = Footer?.LayoutSize.Y ?? 0; if (headerH != headerHeight || footerH != footerHeight) { headerHeight = headerH; footerHeight = footerH; updateSectionsMargin(); } float currentScroll = Math.Max(0, ScrollContainer.Current); if (currentScroll != lastKnownScroll) { lastKnownScroll = currentScroll; if (expandableHeader != null && fixedHeader != null) { float offset = Math.Min(expandableHeader.LayoutSize.Y, currentScroll); expandableHeader.Y = -offset; fixedHeader.Y = -offset + expandableHeader.LayoutSize.Y; } Drawable bestMatch = null; float minDiff = float.MaxValue; foreach (var section in sections) { float diff = Math.Abs(ScrollContainer.GetChildPosInContent(section) - currentScroll); if (diff < minDiff) { minDiff = diff; bestMatch = section; } } if (bestMatch != null) { SelectedSection.Value = bestMatch; } } }
private bool moveItemToTargetPosition(DrawableLyricEditListItem item, float spacing) { // do not scroll if position is smaller then spacing. var scrollPosition = ScrollContainer.GetChildPosInContent(item); if (scrollPosition < spacing) { return(false); } // do not scroll if posiiton is too large and not able to move to target position. var itemHeight = item.Height; var contentHeight = ScrollContainer.ScrollContent.Height; var containerHeight = ScrollContainer.DrawHeight; if (contentHeight - scrollPosition + itemHeight < containerHeight - spacing) { return(false); } ScrollContainer.ScrollTo(scrollPosition - spacing); return(true); }
public void ScrollTo(Drawable section) => scrollContainer.ScrollTo(scrollContainer.GetChildPosInContent(section) - (FixedHeader?.BoundingBox.Height ?? 0));