IEnumerable <ParserNode> NavigateCell(ParserNavigationDirectionEnum direction, bool shiftDown, bool keepSelections) { var startColumn = parent.children.IndexOf(this); var startRow = parent.parent.children.IndexOf(parent); var endColumn = startColumn; var endRow = startRow; switch (direction) { case ParserNavigationDirectionEnum.Up: endRow -= 1; break; case ParserNavigationDirectionEnum.Down: endRow += 1; break; case ParserNavigationDirectionEnum.Left: endColumn -= 1; break; case ParserNavigationDirectionEnum.Right: endColumn += 1; break; case ParserNavigationDirectionEnum.Home: endColumn = 0; break; case ParserNavigationDirectionEnum.End: endColumn = int.MaxValue; break; case ParserNavigationDirectionEnum.PgUp: endRow = 0; break; case ParserNavigationDirectionEnum.PgDn: endRow = int.MaxValue; break; case ParserNavigationDirectionEnum.Row: startColumn = 0; endColumn = int.MaxValue; break; case ParserNavigationDirectionEnum.Column: startRow = 0; endRow = int.MaxValue; break; } if (!shiftDown) { if (keepSelections) { endRow = Math.Max(0, Math.Min(endRow, parent.parent.children.Count - 1)); endColumn = Math.Max(0, Math.Min(endColumn, parent.parent.children[endRow].children.Count - 1)); } if ((endRow >= 0) && (endRow < parent.parent.children.Count)) { if ((endColumn >= 0) && (endColumn < parent.parent.children[endRow].children.Count)) { yield return(parent.parent.children[endRow].children[endColumn]); } } yield break; } var minRow = Math.Max(0, Math.Min(startRow, endRow)); var minColumn = Math.Max(0, Math.Min(startColumn, endColumn)); var maxRow = Math.Min(parent.parent.children.Count - 1, Math.Max(startRow, endRow)); var maxColumn = Math.Max(startColumn, endColumn); // Can't force any upper bound; different rows could have different numbers of columns for (var row = minRow; row <= maxRow; ++row) { for (var column = minColumn; column <= Math.Min(parent.parent.children[row].children.Count - 1, maxColumn); ++column) { yield return(parent.parent.children[row].children[column]); } } }
public IEnumerable <ParserNode> Navigate(ParserNavigationDirectionEnum direction, bool shiftDown, bool keepSelections) { switch (ParserNavigationType) { case ParserNavigationTypeEnum.Regular: return(NavigateRegular(direction, shiftDown, keepSelections)); case ParserNavigationTypeEnum.FirstChild: return(NavigateFirstChild()); case ParserNavigationTypeEnum.Cell: return(NavigateCell(direction, shiftDown, keepSelections)); default: throw new ArgumentException($"Invalid {nameof(ParserNavigationType)}"); } }
public IEnumerable<ParserNode> Navigate(ParserNavigationDirectionEnum direction, bool shiftDown) { switch (ParserNavigationType) { case ParserNavigationTypeEnum.Regular: return NavigateRegular(direction, shiftDown); case ParserNavigationTypeEnum.FirstChild: return NavigateFirstChild(); case ParserNavigationTypeEnum.Cell: return NavigateCell(direction, shiftDown); default: throw new ArgumentException($"Invalid {nameof(ParserNavigationType)}"); } }
IEnumerable<ParserNode> NavigateCell(ParserNavigationDirectionEnum direction, bool shiftDown) { var startColumn = parent.children.IndexOf(this); var startRow = parent.parent.children.IndexOf(parent); var endColumn = startColumn; var endRow = startRow; switch (direction) { case ParserNavigationDirectionEnum.Up: endRow -= 1; break; case ParserNavigationDirectionEnum.Down: endRow += 1; break; case ParserNavigationDirectionEnum.Left: endColumn -= 1; break; case ParserNavigationDirectionEnum.Right: endColumn += 1; break; case ParserNavigationDirectionEnum.Home: endColumn = 0; break; case ParserNavigationDirectionEnum.End: endColumn = int.MaxValue; break; case ParserNavigationDirectionEnum.PgUp: endRow = 0; break; case ParserNavigationDirectionEnum.PgDn: endRow = int.MaxValue; break; case ParserNavigationDirectionEnum.Row: startColumn = 0; endColumn = int.MaxValue; break; case ParserNavigationDirectionEnum.Column: startRow = 0; endRow = int.MaxValue; break; } if (!shiftDown) { var row = Math.Max(0, Math.Min(endRow, parent.parent.children.Count - 1)); var column = Math.Max(0, Math.Min(endColumn, parent.parent.children[row].children.Count - 1)); yield return parent.parent.children[row].children[column]; yield break; } var minRow = Math.Max(0, Math.Min(startRow, endRow)); var minColumn = Math.Max(0, Math.Min(startColumn, endColumn)); var maxRow = Math.Min(parent.parent.children.Count - 1, Math.Max(startRow, endRow)); var maxColumn = Math.Max(startColumn, endColumn); // Can't force any upper bound; different rows could have different numbers of columns for (var row = minRow; row <= maxRow; ++row) for (var column = minColumn; column <= Math.Min(parent.parent.children[row].children.Count - 1, maxColumn); ++column) yield return parent.parent.children[row].children[column]; }
IEnumerable<ParserNode> NavigateRegular(ParserNavigationDirectionEnum direction, bool shiftDown) { switch (direction) { case ParserNavigationDirectionEnum.Up: case ParserNavigationDirectionEnum.Down: { if (shiftDown) yield return this; var index = parent?.children.IndexOf(this); if ((index == -1) || (index == null)) { yield return this; yield break; } var offset = direction == ParserNavigationDirectionEnum.Up ? -1 : 1; index = Math.Max(0, Math.Min(index.Value + offset, parent.children.Count - 1)); yield return parent.children[index.Value]; } break; case ParserNavigationDirectionEnum.Left: yield return parent == null ? this : parent; break; case ParserNavigationDirectionEnum.Right: if (!children.Any()) yield return this; foreach (var child in children) { yield return child; if (!shiftDown) break; } break; case ParserNavigationDirectionEnum.Row: case ParserNavigationDirectionEnum.Column: if (parent == null) { yield return this; break; } foreach (var child in parent.children) yield return child; break; case ParserNavigationDirectionEnum.Home: case ParserNavigationDirectionEnum.PgUp: { if (parent == null) { yield return this; yield break; } var index = parent.children.IndexOf(this); if (!shiftDown) yield return parent.children.First(); else foreach (var child in parent.children.Take(index + 1)) yield return child; } break; case ParserNavigationDirectionEnum.End: case ParserNavigationDirectionEnum.PgDn: { if (parent == null) { yield return this; yield break; } var index = parent.children.IndexOf(this); if (!shiftDown) yield return parent.children.Last(); else foreach (var child in parent.children.Skip(index)) yield return child; } break; default: yield return this; break; } }
IEnumerable <ParserNode> NavigateRegular(ParserNavigationDirectionEnum direction, bool shiftDown, bool keepSelections) { switch (direction) { case ParserNavigationDirectionEnum.Up: case ParserNavigationDirectionEnum.Down: { if (shiftDown) { yield return(this); } var index = parent?.children.IndexOf(this) ?? -1; if (index == -1) { if (keepSelections) { yield return(this); } break; } index += direction == ParserNavigationDirectionEnum.Up ? -1 : 1; if (keepSelections) { index = Math.Max(0, Math.Min(index, parent.children.Count - 1)); } if ((index >= 0) && (index < parent.children.Count)) { yield return(parent.children[index]); } } break; case ParserNavigationDirectionEnum.Left: if ((parent != null) || (keepSelections)) { yield return(parent ?? this); } break; case ParserNavigationDirectionEnum.Right: if ((keepSelections) && (!children.Any())) { yield return(this); } foreach (var child in children) { yield return(child); if (!shiftDown) { break; } } break; case ParserNavigationDirectionEnum.Row: case ParserNavigationDirectionEnum.Column: if (parent == null) { if (keepSelections) { yield return(this); } break; } foreach (var child in parent.children) { yield return(child); } break; case ParserNavigationDirectionEnum.Home: case ParserNavigationDirectionEnum.PgUp: { if (parent == null) { if (keepSelections) { yield return(this); } break; } var index = parent.children.IndexOf(this); if (!shiftDown) { yield return(parent.children.First()); } else { foreach (var child in parent.children.Take(index + 1)) { yield return(child); } } } break; case ParserNavigationDirectionEnum.End: case ParserNavigationDirectionEnum.PgDn: { if (parent == null) { if (keepSelections) { yield return(this); } break; } var index = parent.children.IndexOf(this); if (!shiftDown) { yield return(parent.children.Last()); } else { foreach (var child in parent.children.Skip(index)) { yield return(child); } } } break; default: if (keepSelections) { yield return(this); } break; } }