protected override Line CreateLine(FillDirection direction, int extentOffset, int breadthOffset, int availableBreadth, RecyclerView.Recycler recycler, RecyclerView.State state, IndexPath nextVisibleItem, bool isNewGroup ) { var item = GetFlatItemIndex(nextVisibleItem); var view = recycler.GetViewForPosition(item, state); Debug.Assert(view is SelectorItem, "view is SelectorItem (we should never be given a group header)"); var size = AddViewAtOffset(view, direction, extentOffset, breadthOffset, availableBreadth); var physicalSize = size.LogicalToPhysicalPixels(); var breadth = (int)(ScrollOrientation == Orientation.Vertical ? physicalSize.Width : physicalSize.Height); return(new Line { NumberOfViews = 1, Extent = (int)(ScrollOrientation == Orientation.Vertical ? physicalSize.Height : physicalSize.Width), FirstItem = nextVisibleItem, LastItem = nextVisibleItem, Breadth = breadth }); }
public CollectionChangedOperation(IndexPath startingIndex, int range, NotifyCollectionChangedAction action, Element elementType) { StartingIndex = startingIndex; Range = range; Action = action; ElementType = elementType; }
private void AddItems(int firstItem, int count, int section) { var unoIndex = IndexPath.FromRowSection(firstItem, section); var recyclerViewIndex = GetDisplayIndexFromIndexPath(unoIndex); NativePanel?.CurrentAdapter?.NotifyItemRangeInserted(recyclerViewIndex, count); }
private IndexPath?GetDecrementedItemIndex(IndexPath currentItem) { if (!IsGrouping) { if (currentItem.Section > 0) { throw new InvalidOperationException("Received an index with non-zero group, but source is not grouped."); } if (currentItem.Row == 0) { return(null); } return(IndexPath.FromRowSection(currentItem.Row - 1, 0)); } if (currentItem.Row == 0) { var nextSection = GetNextNonEmptySection(currentItem.Section, -1); if (!nextSection.HasValue) { //No previous non-empty sections return(null); } return(IndexPath.FromRowSection(GetDisplayGroupCount(nextSection.Value) - 1, nextSection.Value)); } return(IndexPath.FromRowSection(currentItem.Row - 1, currentItem.Section)); }
protected override Line CreateLine(GeneratorDirection direction, int extentOffset, int breadthOffset, int availableBreadth, RecyclerView.Recycler recycler, RecyclerView.State state, IndexPath nextVisibleItem, bool isNewGroup ) { var item = GetFlatItemIndex(nextVisibleItem); var view = recycler.GetViewForPosition(item, state); if (!(view is SelectorItem)) { throw new InvalidOperationException($"Expected {nameof(SelectorItem)} but received {view?.GetType().ToString() ?? "<null>"}"); } var size = AddViewAtOffset(view, direction, extentOffset, breadthOffset, availableBreadth); var physicalSize = size.LogicalToPhysicalPixels(); var breadth = (int)(ScrollOrientation == Orientation.Vertical ? physicalSize.Width : physicalSize.Height); return(new Line { NumberOfViews = 1, Extent = (int)(ScrollOrientation == Orientation.Vertical ? physicalSize.Height : physicalSize.Width), FirstItem = nextVisibleItem, LastItem = nextVisibleItem, Breadth = breadth }); }
static void Postfix(ref IndexPath __result, LevelInfo level) { if (CustomLevelManager.Instance.CurrentFolder.HasChildren()) { if (level is CustomLevelInfo) { __result = new IndexPath(1, CustomLevelManager.Instance.CurrentFolder.Children.IndexOf((level as CustomLevelInfo).Info)); } else if (level is CustomLevelFolderInfo) { __result = new IndexPath(1, CustomLevelManager.Instance.CurrentFolder.Children.IndexOf((level as CustomLevelFolderInfo).FolderInfo)); } } else { if (level is CustomLevelInfo) { __result = new IndexPath(1, CustomLevelManager.Instance.NestedItems.IndexOf((level as CustomLevelInfo).Info)); } else if (level is CustomLevelFolderInfo) { __result = new IndexPath(1, CustomLevelManager.Instance.NestedItems.IndexOf((level as CustomLevelFolderInfo).FolderInfo)); } } }
private static void PreviewGear(GearSelectionController __instance, IndexPath index) { GearInfo gearAtIndex1 = GearDatabase.Instance.GetGearAtIndex(index); if (gearAtIndex1 == (GearInfo)null) { return; } List <GearInfo> toBeCachedGear = new List <GearInfo>(); for (int steps = -__instance.preloadedItemsPerSide; steps <= __instance.preloadedItemsPerSide; ++steps) { GearInfo gearAtIndex2 = GearDatabase.Instance.GetGearAtIndex(index.Horizontal(steps)); if (gearAtIndex2 != (GearInfo)null) { toBeCachedGear.Add(gearAtIndex2); } } if (gearAtIndex1 is CustomGearFolderInfo) { __instance.previewCustomizer.PreviewItem(null, toBeCachedGear); } else { __instance.previewCustomizer.PreviewItem(gearAtIndex1, toBeCachedGear); } }
/// <summary> /// Get the last item in the source, or null if the source is empty. /// </summary> internal IndexPath?GetLastItem() { if (!IsGrouping) { var itemCount = NumberOfItems; if (itemCount <= 0) { return(null); } return(IndexPath.FromRowSection(itemCount - 1, 0)); } for (int i = NumberOfDisplayGroups - 1; i >= 0; i--) { var count = GetDisplayGroupCount(i); if (count > 0) { return(IndexPath.FromRowSection(count - 1, i)); } } // No non-empty groups return(null); }
static void Postfix(ref int __result, IndexPath index) { var officialGear = Traverse.Create(GearDatabase.Instance).Field("gearListSource").GetValue <GearInfo[][][]>(); if (index[0] < 0) { return; } // return out if it's not one of the tabs XLMenuMod is aware of. if (index[1] < 0 || index[1] > (officialGear[index[0]].Length * 2) - 1) { return; } bool isCustom = index[0] < officialGear.Length && index[1] >= officialGear[index[0]].Length; if (isCustom && index.depth >= 3) { __result = CustomGearManager.Instance.CurrentFolder.HasChildren() ? CustomGearManager.Instance.CurrentFolder.Children.Count : CustomGearManager.Instance.NestedItems.Count; } else if (!isCustom && index.depth >= 3) { __result = CustomGearManager.Instance.CurrentFolder.HasChildren() ? CustomGearManager.Instance.CurrentFolder.Children.Count : CustomGearManager.Instance.NestedOfficialItems.Count; } if (Main.Settings.HideOfficialGear && !isCustom && index.depth >= 2 && index[1] != 0 && index[1] != 1) { __result = 0; } }
public void Simple_Index() { var a = new IndexPath(1); Assert.Equal(1, a.GetSize()); Assert.Equal(1, a.GetAt(0)); }
public static void Traverse( SelectionNode root, bool realizeChildren, Action <TreeWalkNodeInfo> nodeAction) { var pendingNodes = new List <TreeWalkNodeInfo>(); var current = new IndexPath(null); pendingNodes.Add(new TreeWalkNodeInfo(root, current)); while (pendingNodes.Count > 0) { var nextNode = pendingNodes.Last(); pendingNodes.RemoveAt(pendingNodes.Count - 1); int count = realizeChildren ? nextNode.Node.DataCount : nextNode.Node.ChildrenNodeCount; for (int i = count - 1; i >= 0; i--) { var child = nextNode.Node.GetAt(i, realizeChildren); var childPath = nextNode.Path.CloneWithChildIndex(i); if (child != null) { pendingNodes.Add(new TreeWalkNodeInfo(child, childPath, nextNode.Node)); } } // Queue the children first and then perform the action. This way // the action can remove the children in the action if necessary nodeAction(nextNode); } }
/// <summary> /// Get the index for the next item after <paramref name="currentItem"/>. /// </summary> internal IndexPath?GetNextItemIndex(IndexPath?currentItem, int direction) { if (!HasItems) { return(null); } if (currentItem == null) { // Null is treated as 'just before the first item.' if (direction == 1) { var firstNonEmptySection = IsGrouping ? GetNextNonEmptySection(-1, 1).Value : 0; return(IndexPath.FromRowSection(0, firstNonEmptySection)); } else { return(null); } } if (direction == 1) { return(GetIncrementedItemIndex(currentItem.Value)); } if (direction == -1) { return(GetDecrementedItemIndex(currentItem.Value)); } throw new ArgumentOutOfRangeException(nameof(direction)); }
partial void NativeReplaceItems(int firstItem, int count, int section) { var unoIndex = IndexPath.FromRowSection(firstItem, section); var recyclerViewIndex = GetDisplayIndexFromIndexPath(unoIndex); NativePanel?.CurrentAdapter?.NotifyItemRangeChanged(recyclerViewIndex, count); }
static void Postfix(GearDatabase __instance, IndexPath index, GearInfo[][][] ___gearListSource, ref GearInfo __result) { if (index.depth < 3) { return; } // return out if it's not one of the tabs XLMenuMod is aware of. if (index[1] < 0 || index[1] > (___gearListSource[index[0]].Length * 2) - 1) { return; } List <ICustomInfo> sourceList = null; if (CustomGearManager.Instance.CurrentFolder.HasChildren()) { sourceList = CustomGearManager.Instance.CurrentFolder.Children; } else { if (index[1] < Enum.GetValues(typeof(GearCategory)).Length&& !CategoryHelper.IsTypeOf(index, GearCategory.SkinTone)) { sourceList = CustomGearManager.Instance.NestedOfficialItems; } else if (index[1] >= Enum.GetValues(typeof(GearCategory)).Length) { sourceList = CustomGearManager.Instance.NestedItems; } } if (sourceList == null) { return; } if (index.LastIndex < 0 || index.LastIndex >= sourceList.Count) { return; } var customInfo = sourceList.ElementAt(index.LastIndex); if (customInfo.GetParentObject() is CustomBoardGearInfo customBoardGearInfo) { __result = customBoardGearInfo; } else if (customInfo.GetParentObject() is CustomCharacterGearInfo customCharacterGearInfo) { __result = customCharacterGearInfo; } else if (customInfo.GetParentObject() is CustomCharacterBodyInfo customCharacterBodyInfo) { __result = customCharacterBodyInfo; } else if (customInfo.GetParentObject() is CustomGearFolderInfo customGearFolderInfo) { __result = customGearFolderInfo; } }
/// <summary> /// Let's populate Item views /// </summary> /// <param name="holder"></param> /// <param name="indexPath"></param> public override void OnBindItemViewHolder(RecyclerView.ViewHolder holder, IndexPath indexPath) { var viewHolder = (holder as ItemViewHolder); var movieInfo = this.GetItem(indexPath); viewHolder.txvMovieName.Text = movieInfo.Name; viewHolder.txvOtherInfo.Text = $"Rank: {movieInfo.Rank}, Year: {movieInfo.Year}"; }
public TreeWalkNodeInfo(SelectionNode node, IndexPath indexPath) { node = node ?? throw new ArgumentNullException(nameof(node)); Node = node; Path = indexPath; ParentNode = null; }
private void RemoveItems(int firstItem, int count, int section) { var unoIndex = IndexPath.FromRowSection(firstItem, section); var recyclerViewIndex = GetDisplayIndexFromIndexPath(unoIndex); NativePanel?.CurrentAdapter?.NotifyItemRangeRemoved(recyclerViewIndex, count); NativePanel?.NativeLayout?.NotifyCollectionChange(groupOperation: null); }
public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath) { using ( _trace.WriteEventActivity( TraceProvider.ListViewBaseSource_GetCellStart, TraceProvider.ListViewBaseSource_GetCellStop ) ) { // Marks this item to be materialized, so its actual measured size // is used during the calculation of the layout. // This is required for paged lists, so that the layout calculation // does not eagerly get all the items of the ItemsSource. UpdateLastMaterializedItem(indexPath); var index = Owner?.XamlParent?.GetIndexFromIndexPath(IndexPath.FromNSIndexPath(indexPath)) ?? -1; var identifier = GetReusableCellIdentifier(indexPath); var listView = (NativeListViewBase)collectionView; var cell = (ListViewBaseInternalContainer)collectionView.DequeueReusableCell(identifier, indexPath); using (cell.InterceptSetNeedsLayout()) { var selectorItem = cell.Content as SelectorItem; if (selectorItem == null || // If it's not a generated container then it must be an item that returned true for IsItemItsOwnContainerOverride (eg an // explicitly-defined ListViewItem), and shouldn't be recycled for a different item. !selectorItem.IsGeneratedContainer) { cell.Owner = Owner; selectorItem = Owner?.XamlParent?.GetContainerForIndex(index) as SelectorItem; cell.Content = selectorItem; if (this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { this.Log().Debug($"Creating new view at indexPath={indexPath}."); } FrameworkElement.InitializePhaseBinding(selectorItem); } else if (this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { this.Log().Debug($"Reusing view at indexPath={indexPath}, previously bound to {selectorItem.DataContext}."); } Owner?.XamlParent?.PrepareContainerForIndex(selectorItem, index); // Normally this happens when the SelectorItem.Content is set, but there's an edge case where after a refresh, a // container can be dequeued which happens to have had exactly the same DataContext as the new item. cell.ClearMeasuredSize(); } Owner?.XamlParent?.TryLoadMoreItems(index); return(cell); } }
internal override void OnItemsSourceSingleCollectionChanged(object sender, NotifyCollectionChangedEventArgs c, int section) { // Get SelectedIndex before calling base, as a quick workaround for side-effect in FlipView.Android that changes the SelectedIndex, to avoid incrementing it twice var selectedIndexToSet = SelectedIndex; base.OnItemsSourceSingleCollectionChanged(sender, c, section); switch (c.Action) { case NotifyCollectionChangedAction.Add: //Advance SelectedIndex if items are being inserted before it var newIndex = GetIndexFromIndexPath(IndexPath.FromRowSection(c.NewStartingIndex, section)); if (selectedIndexToSet >= newIndex) { selectedIndexToSet += c.NewItems.Count; SelectedIndex = selectedIndexToSet; } break; case NotifyCollectionChangedAction.Remove: { var oldIndex = GetIndexFromIndexPath(IndexPath.FromRowSection(c.OldStartingIndex, section)); if (selectedIndexToSet >= oldIndex && selectedIndexToSet < oldIndex + c.OldItems.Count) { //Deset if selected item is being removed SelectedIndex = -1; } else if (selectedIndexToSet >= oldIndex + c.OldItems.Count) { //Decrement SelectedIndex if items are removed before it selectedIndexToSet -= c.OldItems.Count; SelectedIndex = selectedIndexToSet; } } break; case NotifyCollectionChangedAction.Replace: { var oldIndex = GetIndexFromIndexPath(IndexPath.FromRowSection(c.OldStartingIndex, section)); if (selectedIndexToSet >= oldIndex && selectedIndexToSet < oldIndex + c.OldItems.Count) { //Deset if selected item is being replaced SelectedIndex = -1; } } break; case NotifyCollectionChangedAction.Reset: if (SelectedIndexPath?.Section == section) { SelectedIndex = -1; } break; } //TODO: handle other cases (PBI #27502) }
public override void ReloadSections(NSIndexSet sections) { NativeLayout?.NotifyCollectionChange(new CollectionChangedOperation( IndexPath.FromRowSection(0, (int)sections.FirstIndex), (int)sections.Count, NotifyCollectionChangedAction.Replace, CollectionChangedOperation.Element.Group )); base.ReloadSections(sections); }
public void Unequal_Null_Path() { var a = new IndexPath(null); var b = new IndexPath(2); Assert.False(a == b); Assert.True(a != b); Assert.False(a.Equals(b)); Assert.Equal(-1, a.CompareTo(b)); Assert.NotEqual(a.GetHashCode(), b.GetHashCode()); }
public void Default_Is_Null_Path() { var a = new IndexPath(null); var b = default(IndexPath); Assert.True(a == b); Assert.False(a != b); Assert.True(a.Equals(b)); Assert.Equal(0, a.CompareTo(b)); Assert.Equal(a.GetHashCode(), b.GetHashCode()); }
private static IndexPath StartPath(IndexPath path, int length) { var subPath = new List <int>(); for (int i = 0; i < length; i++) { subPath.Add(path.GetAt(i)); } return(new IndexPath(subPath)); }
public void Equal_Paths() { var a = new IndexPath(1); var b = new IndexPath(1); Assert.True(a == b); Assert.False(a != b); Assert.True(a.Equals(b)); Assert.Equal(0, a.CompareTo(b)); Assert.Equal(a.GetHashCode(), b.GetHashCode()); }
public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath) { using ( _trace.WriteEventActivity( TraceProvider.ListViewBaseSource_GetCellStart, TraceProvider.ListViewBaseSource_GetCellStop ) ) { // Marks this item to be materialized, so its actual measured size // is used during the calculation of the layout. // This is required for paged lists, so that the layout calculation // does not eagerly get all the items of the ItemsSource. if (!_materializedItems.Contains(indexPath)) { _materializedItems.Add(indexPath); } var index = Owner?.XamlParent?.GetIndexFromIndexPath(IndexPath.FromNSIndexPath(indexPath)) ?? -1; var identifier = GetReusableCellIdentifier(indexPath); var listView = (NativeListViewBase)collectionView; var cell = (ListViewBaseInternalContainer)collectionView.DequeueReusableCell(identifier, indexPath); using (cell.InterceptSetNeedsLayout()) { var selectorItem = cell.Content as SelectorItem; if (selectorItem == null) { cell.Owner = Owner; selectorItem = Owner?.XamlParent?.GetContainerForIndex(index) as SelectorItem; cell.Content = selectorItem; if (this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { this.Log().Debug($"Creating new view at indexPath={indexPath}."); } FrameworkElement.InitializePhaseBinding(selectorItem); } else if (this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { this.Log().Debug($"Reusing view at indexPath={indexPath}, previously bound to {selectorItem.DataContext}."); } Owner?.XamlParent?.PrepareContainerForIndex(selectorItem, index); } Owner?.XamlParent?.TryLoadMoreItems(index); return(cell); } }
static bool Prefix(LevelSelectionController __instance, IndexPath index) { if (CustomLevelManager.Instance.LastSelectedTime != 0d && Time.realtimeSinceStartup - CustomLevelManager.Instance.LastSelectedTime < 0.25f) { return(false); } CustomLevelManager.Instance.LastSelectedTime = Time.realtimeSinceStartup; var level = Traverse.Create(__instance).Method("GetLevelForIndex", index).GetValue <LevelInfo>(); if (level is CustomLevelFolderInfo selectedFolder) { selectedFolder.FolderInfo.Children = CustomLevelManager.Instance.SortList(selectedFolder.FolderInfo.Children); var currentIndexPath = Traverse.Create(__instance.listView).Property <IndexPath>("currentIndexPath"); if (selectedFolder.FolderInfo.GetName() == "..\\") { CustomLevelManager.Instance.CurrentFolder = selectedFolder.FolderInfo.Parent; currentIndexPath.Value = __instance.listView.currentIndexPath.Up(); __instance.listView.UpdateList(); __instance.listView.SetHighlighted(currentIndexPath.Value, true); } else { CustomLevelManager.Instance.CurrentFolder = selectedFolder.FolderInfo; if (CustomLevelManager.Instance.CurrentFolder.Parent != null) { currentIndexPath.Value = __instance.listView.currentIndexPath.Sub(CustomLevelManager.Instance.CurrentFolder.Parent.Children.IndexOf(CustomLevelManager.Instance.CurrentFolder)); } else { currentIndexPath.Value = __instance.listView.currentIndexPath.Sub(CustomLevelManager.Instance.NestedItems.IndexOf(CustomLevelManager.Instance.CurrentFolder)); } __instance.listView.UpdateList(); EventSystem.current.SetSelectedGameObject(null); } return(false); } else if (level is CustomLevelInfo selectedLevel) { level = selectedLevel; return(true); } else { CustomLevelManager.Instance.CurrentFolder = null; return(true); } }
protected override object GetItemAt(IndexPath indexPath) { if (ItemsSource == null) { return(null); } #if MVX_DBG UnityEngine.Debug.LogError("MvxCollection view getting element!!!:" + indexPath.Index + ":" + indexPath.Row); UnityEngine.Debug.LogError("Item source type:" + ItemsSource); #endif return(ItemsSource.ElementAt(indexPath.Row)); }
public void Null_Equality() { var a = new IndexPath(null); var b = new IndexPath(1); // Implementing operator == on a struct automatically implements an operator which // accepts null, so make sure this does something useful. Assert.True(a == null); Assert.False(a != null); Assert.False(b == null); Assert.True(b != null); }
/// <summary> /// Let's populate Item views /// </summary> /// <param name="holder"></param> /// <param name="indexPath"></param> /// <remarks> /// You can set the events in this block /// </remarks> public override void OnBindItemViewHolder(RecyclerView.ViewHolder holder, IndexPath indexPath) { var viewHolder = (holder as ItemViewHolder); var movieInfo = this.GetItem(indexPath); viewHolder.ClickAction = () => this.OnItemClick(new ItemClickEventArgs() { IndexPath = indexPath }); viewHolder.txvMovieName.Text = movieInfo.Name; viewHolder.txvOtherInfo.Text = $"Rank: {movieInfo.Rank}, Year: {movieInfo.Year}"; }
protected override void OnContentChanged(object oldContent, object newContent) { if ((_partPaintArea != null) && (_partMainContent != null)) { var oldIndex = IndexPath.Evaluate <int>(oldContent); var newIndex = IndexPath.Evaluate <int>(newContent); _partPaintArea.Fill = CreateBrushFromVisual(_partMainContent); BeginAnimateContentReplacement(oldIndex <= newIndex); } base.OnContentChanged(oldContent, newContent); }