/// <summary> /// Gets the span of a column. This is empty if the column isn't present. /// </summary> /// <param name="column">Column</param> /// <returns></returns> public VST.Span GetColumnSpan(HexColumnType column) { switch (column) { case HexColumnType.Offset: return OffsetSpan; case HexColumnType.Values: return ValuesSpan; case HexColumnType.Ascii: return AsciiSpan; default: throw new ArgumentOutOfRangeException(nameof(column)); } }
public RectangleElement(HexColumnType column, Rect rect, Brush brush, Pen pen) { Canvas.SetTop(this, 0); Column = column; this.rect = rect; this.brush = brush; this.pen = pen; }
/// <summary> /// Gets the span of a column. This is empty if the column isn't present. /// </summary> /// <param name="column">Column</param> /// <returns></returns> public VST.Span GetColumnSpan(HexColumnType column) { switch (column) { case HexColumnType.Offset: return(OffsetSpan); case HexColumnType.Values: return(ValuesSpan); case HexColumnType.Ascii: return(AsciiSpan); default: throw new ArgumentOutOfRangeException(nameof(column)); } }
static string GetClassificationTypeName(HexColumnType column) { switch (column) { case HexColumnType.Values: return(CTC.ThemeClassificationTypeNameKeys.HexHighlightedValuesColumn); case HexColumnType.Ascii: return(CTC.ThemeClassificationTypeNameKeys.HexHighlightedAsciiColumn); case HexColumnType.Offset: default: throw new ArgumentOutOfRangeException(nameof(column)); } }
public override int GetCharsPerCellIncludingSeparator(HexColumnType column) { switch (column) { case HexColumnType.Offset: return(offsetFormatter.FormattedLength); case HexColumnType.Values: return(valueFormatter.FormattedLength + 1); case HexColumnType.Ascii: return(1); default: throw new ArgumentOutOfRangeException(nameof(column)); } }
/// <summary> /// Returns true if a column is present /// </summary> /// <param name="column">Column</param> /// <returns></returns> public bool IsColumnPresent(HexColumnType column) { switch (column) { case HexColumnType.Offset: return(IsOffsetColumnPresent); case HexColumnType.Values: return(IsValuesColumnPresent); case HexColumnType.Ascii: return(IsAsciiColumnPresent); default: throw new ArgumentOutOfRangeException(nameof(column)); } }
/// <summary> /// Gets the span of a column /// </summary> /// <param name="column">Colum</param> /// <param name="onlyVisibleCells">true to only include visible values, false to include the full column</param> /// <returns></returns> public VST.Span GetSpan(HexColumnType column, bool onlyVisibleCells) { switch (column) { case HexColumnType.Offset: return(GetOffsetSpan()); case HexColumnType.Values: return(GetValuesSpan(onlyVisibleCells)); case HexColumnType.Ascii: return(GetAsciiSpan(onlyVisibleCells)); default: throw new ArgumentOutOfRangeException(nameof(column)); } }
static HexColumnType Toggle(HexColumnType column) { switch (column) { case HexColumnType.Values: return(HexColumnType.Ascii); case HexColumnType.Ascii: return(HexColumnType.Values); case HexColumnType.Offset: default: throw new ArgumentOutOfRangeException(nameof(column)); } }
/// <summary> /// Constructor /// </summary> /// <param name="column">Column</param> /// <param name="bufferPosition">Buffer position</param> /// <param name="cellPosition">Position within the cell</param> public HexCellPosition(HexColumnType column, HexBufferPoint bufferPosition, int cellPosition) { if (column != HexColumnType.Values && column != HexColumnType.Ascii) { throw new ArgumentOutOfRangeException(nameof(column)); } if (bufferPosition.IsDefault) { throw new ArgumentException(); } if (cellPosition < 0) { throw new ArgumentOutOfRangeException(nameof(cellPosition)); } Column = column; BufferPosition = bufferPosition; CellPosition = cellPosition; }
/// <summary> /// Constructor /// </summary> /// <param name="activeColumn">Active column</param> /// <param name="valuePosition">Position in the values column</param> /// <param name="asciiPosition">Position in the ASCII column</param> public HexColumnPosition(HexColumnType activeColumn, HexCellPosition valuePosition, HexCellPosition asciiPosition) { if (activeColumn != HexColumnType.Values && activeColumn != HexColumnType.Ascii) { throw new ArgumentOutOfRangeException(nameof(activeColumn)); } if (valuePosition.IsDefault || valuePosition.Column != HexColumnType.Values) { throw new ArgumentException(); } if (asciiPosition.IsDefault || asciiPosition.Column != HexColumnType.Ascii) { throw new ArgumentException(); } ActiveColumn = activeColumn; ValuePosition = valuePosition; AsciiPosition = asciiPosition; }
public override HexCaretPosition MoveTo(HexColumnType column, HexBufferPoint position, HexMoveToFlags flags) { if (column != HexColumnType.Values && column != HexColumnType.Ascii) { throw new ArgumentOutOfRangeException(nameof(column)); } if (position.IsDefault) { throw new ArgumentException(); } if (!hexView.BufferLines.IsValidPosition(position)) { throw new ArgumentOutOfRangeException(nameof(position)); } var cellPos = column == HexColumnType.Values ? CreateValuesCellPosition(position) : new HexCellPosition(column, position, 0); var colPos = CreateColumnPosition(cellPos); return(MoveTo(colPos, flags)); }
Rect GetCaretRect(HexViewLine line, bool drawOverwriteMode, HexColumnType column, HexCell cell, int cellPosition) { if (cell == null) { return(new Rect()); } int linePosition = cell.CellSpan.Start + Math.Max(0, Math.Min(cell.CellSpan.Length - 1, cellPosition)); if (hexCaret.CurrentPosition.ActiveColumn != column) { var r = ToRect(line.GetNormalizedTextBounds(cell.CellSpan)); return(new Rect(r.X, r.Bottom - INACTIVE_CARET_HEIGHT, r.Width, INACTIVE_CARET_HEIGHT)); } else if (drawOverwriteMode) { var textBounds = line.GetExtendedCharacterBounds(linePosition); var left = textBounds.Left; var top = line.TextTop; var width = textBounds.Width; var height = line.TextHeight; return(new Rect(left, top, width, height)); } else { double left; if (linePosition != 0 && linePosition <= line.BufferLine.Text.Length) { left = line.GetExtendedCharacterBounds(linePosition - 1).Trailing; } else { left = line.GetExtendedCharacterBounds(linePosition).Leading; } var top = line.TextTop; var width = SystemParameters.CaretWidth; var height = line.TextHeight; return(new Rect(left, top, width, height)); } }
public override void SelectAndMoveCaret(HexColumnType column, HexBufferPoint anchorPoint, HexBufferPoint activePoint, bool alignPoints, VSTE.EnsureSpanVisibleOptions? scrollOptions) { if (anchorPoint.IsDefault) throw new ArgumentException(); if (activePoint.IsDefault) throw new ArgumentException(); if (anchorPoint == activePoint) Selection.Clear(); else Selection.Select(anchorPoint, activePoint, alignPoints); MoveCaretToSelection(anchorPoint, activePoint); if (scrollOptions == null) return; var options = Selection.IsReversed ? VSTE.EnsureSpanVisibleOptions.ShowStart | VSTE.EnsureSpanVisibleOptions.MinimumScroll : VSTE.EnsureSpanVisibleOptions.ShowStart; var flags = Caret.Position.Position.ActiveColumn == HexColumnType.Values ? HexSpanSelectionFlags.Values : HexSpanSelectionFlags.Ascii; flags |= HexSpanSelectionFlags.Cell; if (activePoint > anchorPoint) ViewScroller.EnsureSpanVisible(new HexBufferSpan(anchorPoint, activePoint), flags, scrollOptions.Value & ~VSTE.EnsureSpanVisibleOptions.ShowStart); else ViewScroller.EnsureSpanVisible(new HexBufferSpan(activePoint, anchorPoint), flags, scrollOptions.Value | VSTE.EnsureSpanVisibleOptions.ShowStart); }
static string GetClassificationTypeName(HexColumnType column) { switch (column) { case HexColumnType.Values: return CTC.ThemeClassificationTypeNameKeys.HexHighlightedValuesColumn; case HexColumnType.Ascii: return CTC.ThemeClassificationTypeNameKeys.HexHighlightedAsciiColumn; case HexColumnType.Offset: default: throw new ArgumentOutOfRangeException(nameof(column)); } }
/// <summary> /// Moves the caret to a new position /// </summary> /// <param name="column">Column</param> /// <param name="position">Position</param> /// <param name="flags">Flags</param> /// <returns></returns> public abstract HexCaretPosition MoveTo(HexColumnType column, HexBufferPoint position, HexMoveToFlags flags);
/// <summary> /// Returns true if a column is present /// </summary> /// <param name="column">Column</param> /// <returns></returns> public bool IsColumnPresent(HexColumnType column) { switch (column) { case HexColumnType.Offset: return IsOffsetColumnPresent; case HexColumnType.Values: return IsValuesColumnPresent; case HexColumnType.Ascii: return IsAsciiColumnPresent; default: throw new ArgumentOutOfRangeException(nameof(column)); } }
/// <summary> /// Selects data and moves the caret /// </summary> /// <param name="column">Column</param> /// <param name="anchorPoint">Anchor position</param> /// <param name="activePoint">Active position</param> /// <param name="alignPoints">true to align the span to include all bytes of the cells</param> /// <param name="scrollOptions">Scroll options</param> public abstract void SelectAndMoveCaret(HexColumnType column, HexBufferPoint anchorPoint, HexBufferPoint activePoint, bool alignPoints, VSTE.EnsureSpanVisibleOptions? scrollOptions);
public override IEnumerable <IHexTextTagSpan <HexClassificationTag> > GetTags(HexTaggerContext context) { // Minimize color switches between columns: colorize the space between eg. OFFSET/VALUES and // VALUES/ASCII. This results in a small speed up displaying the lines. var columnOrder = context.Line.ColumnOrder; const HexColumnType INVALID_COLUMN = (HexColumnType)(-1); var prevColumnType = INVALID_COLUMN; for (int i = 0; i < columnOrder.Count; i++) { var columnType = columnOrder[i]; if (!context.Line.IsColumnPresent(columnType)) { continue; } if (prevColumnType != INVALID_COLUMN) { // Don't prefer VALUES column since it has two group colors var columnToUse = prevColumnType != HexColumnType.Values ? prevColumnType : columnType; HexClassificationTag tag; switch (columnToUse) { case HexColumnType.Offset: tag = hexClassificationTags.HexOffsetTag; break; case HexColumnType.Ascii: tag = hexClassificationTags.HexAsciiTag; break; case HexColumnType.Values: Debug.Fail("Should never happen"); tag = hexClassificationTags.HexValue0Tag; break; default: throw new InvalidOperationException(); } var start = context.Line.GetSpan(prevColumnType, onlyVisibleCells: false).End; var end = context.Line.GetSpan(columnType, onlyVisibleCells: false).Start; if (start < end) { yield return(new HexTextTagSpan <HexClassificationTag>(VST.Span.FromBounds(start, end), tag)); } } prevColumnType = columnType; } var allValid = context.Line.HexBytes.AllValid; if (allValid == null) { foreach (var cell in context.Line.ValueCells.GetVisibleCells()) { if (!IsValid(cell, context.Line)) { yield return(new HexTextTagSpan <HexClassificationTag>(cell.FullSpan, hexClassificationTags.HexErrorTag)); } } foreach (var cell in context.Line.AsciiCells.GetVisibleCells()) { if (!IsValid(cell, context.Line)) { yield return(new HexTextTagSpan <HexClassificationTag>(cell.FullSpan, hexClassificationTags.HexErrorTag)); } } } else if (!allValid.Value) { yield return(new HexTextTagSpan <HexClassificationTag>(context.Line.GetValuesSpan(onlyVisibleCells: true), hexClassificationTags.HexErrorTag)); yield return(new HexTextTagSpan <HexClassificationTag>(context.Line.GetAsciiSpan(onlyVisibleCells: true), hexClassificationTags.HexErrorTag)); } }
/// <summary> /// Selects data and moves the caret /// </summary> /// <param name="column">Column</param> /// <param name="anchorPoint">Anchor position</param> /// <param name="activePoint">Active position</param> /// <param name="alignPoints">true to align the span to include all bytes of the cells</param> public void SelectAndMoveCaret(HexColumnType column, HexBufferPoint anchorPoint, HexBufferPoint activePoint, bool alignPoints) => SelectAndMoveCaret(column, anchorPoint, activePoint, alignPoints, VSTE.EnsureSpanVisibleOptions.MinimumScroll);
/// <summary> /// Gets the span of a column /// </summary> /// <param name="column">Colum</param> /// <param name="onlyVisibleCells">true to only include visible values, false to include the full column</param> /// <returns></returns> public VST.Span GetSpan(HexColumnType column, bool onlyVisibleCells) { switch (column) { case HexColumnType.Offset: return GetOffsetSpan(); case HexColumnType.Values: return GetValuesSpan(onlyVisibleCells); case HexColumnType.Ascii: return GetAsciiSpan(onlyVisibleCells); default: throw new ArgumentOutOfRangeException(nameof(column)); } }
static ReadOnlyCollection<HexColumnType> TryCreateColumns(HexColumnType[] columnOrders) { var columns = columnOrders.ToList(); if (!columns.Contains(HexColumnType.Offset)) columns.Add(HexColumnType.Offset); if (!columns.Contains(HexColumnType.Values)) columns.Add(HexColumnType.Values); if (!columns.Contains(HexColumnType.Ascii)) columns.Add(HexColumnType.Ascii); if (columns.Count != 3) return null; return new ReadOnlyCollection<HexColumnType>(columns.ToArray()); }
Rect GetCaretRect(HexViewLine line, bool drawOverwriteMode, HexColumnType column, HexCell cell, int cellPosition) { if (cell == null) return new Rect(); int linePosition = cell.CellSpan.Start + Math.Max(0, Math.Min(cell.CellSpan.Length - 1, cellPosition)); if (hexCaret.CurrentPosition.ActiveColumn != column) { var r = ToRect(line.GetNormalizedTextBounds(cell.CellSpan)); return new Rect(r.X, r.Bottom - INACTIVE_CARET_HEIGHT, r.Width, INACTIVE_CARET_HEIGHT); } else if (drawOverwriteMode) { var textBounds = line.GetExtendedCharacterBounds(linePosition); var left = textBounds.Left; var top = line.TextTop; var width = textBounds.Width; var height = line.TextHeight; return new Rect(left, top, width, height); } else { double left; if (linePosition != 0 && linePosition <= line.BufferLine.Text.Length) left = line.GetExtendedCharacterBounds(linePosition - 1).Trailing; else left = line.GetExtendedCharacterBounds(linePosition).Leading; var top = line.TextTop; var width = SystemParameters.CaretWidth; var height = line.TextHeight; return new Rect(left, top, width, height); } }
/// <summary> /// Gets the total number of characters per cell. This includes cell separators if any. /// </summary> /// <returns></returns> public abstract int GetCharsPerCellIncludingSeparator(HexColumnType column);
/// <summary> /// Gets the number of characters per cell value. This value doesn't include any cell separators /// </summary> /// <returns></returns> public abstract int GetCharsPerCell(HexColumnType column);
public override int GetCharsPerCellIncludingSeparator(HexColumnType column) { switch (column) { case HexColumnType.Offset: return offsetFormatter.FormattedLength; case HexColumnType.Values: return valueFormatter.FormattedLength + 1; case HexColumnType.Ascii: return 1; default: throw new ArgumentOutOfRangeException(nameof(column)); } }
/// <summary> /// Moves the caret to a new position /// </summary> /// <param name="column">Column</param> /// <param name="position">Position</param> /// <returns></returns> public HexCaretPosition MoveTo(HexColumnType column, HexBufferPoint position) => MoveTo(column, position, HexMoveToFlags.CaptureHorizontalPosition);
/// <summary> /// Constructor /// </summary> /// <param name="activeColumn">Active column</param> /// <param name="valuePosition">Position in the values column</param> /// <param name="asciiPosition">Position in the ASCII column</param> public HexColumnPosition(HexColumnType activeColumn, in HexCellPosition valuePosition, in HexCellPosition asciiPosition)
/// <summary> /// Selects data and moves the caret /// </summary> /// <param name="column">Column</param> /// <param name="anchorPoint">Anchor position</param> /// <param name="activePoint">Active position</param> /// <param name="alignPoints">true to align the span to include all bytes of the cells</param> /// <param name="scrollOptions">Scroll options</param> public abstract void SelectAndMoveCaret(HexColumnType column, HexBufferPoint anchorPoint, HexBufferPoint activePoint, bool alignPoints, VSTE.EnsureSpanVisibleOptions?scrollOptions);