HexBufferPoint Filter(HexBufferPoint position) { if (position < HexView.BufferLines.BufferStart) return HexView.BufferLines.BufferStart; if (position > HexView.BufferLines.BufferEnd) return HexView.BufferLines.BufferEnd; return position; }
/// <summary> /// Finds the pattern /// </summary> /// <param name="searchRange">Search range</param> /// <param name="startingPosition">Starting position</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public HexBufferSpan?Find(HexBufferSpan searchRange, HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken) { foreach (var span in FindAll(searchRange, startingPosition, options, cancellationToken)) { return(span); } return(null); }
public FindAllCoreEnumerable(ByteHexSearchService owner, HexBufferSpan searchRange, HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken) { this.owner = owner; this.searchRange = searchRange; this.startingPosition = startingPosition; this.options = options; this.cancellationToken = cancellationToken; }
/// <summary> /// Constructor /// </summary> /// <param name="position">Position</param> /// <param name="data">Data</param> public PositionAndData(HexBufferPoint position, byte[] data) { if (position.IsDefault) throw new ArgumentException(); if (data == null) throw new ArgumentNullException(nameof(data)); Position = position; Data = data; }
public override double GetCoordinateAtBufferPosition(HexBufferPoint bufferPosition) { if (bufferPosition.IsDefault) throw new ArgumentException(); if (bufferPosition.Buffer != HexView.Buffer) throw new ArgumentException(); if (!HexView.BufferLines.IsValidPosition(bufferPosition)) throw new ArgumentOutOfRangeException(nameof(bufferPosition)); return Start + HexView.BufferLines.GetLineNumberFromPosition(bufferPosition).ToUInt64(); }
/// <summary> /// Finds the pattern /// </summary> /// <param name="startingPosition">Starting position</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public HexBufferSpan?Find(HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken) { if (startingPosition.IsDefault) { throw new ArgumentException(); } var buffer = startingPosition.Buffer; return(Find(new HexBufferSpan(buffer, buffer.Span), startingPosition, options, cancellationToken)); }
public override void Select(HexBufferPoint anchorPoint, HexBufferPoint activePoint, bool alignPoints) { if (anchorPoint.Buffer != activePoint.Buffer) { throw new ArgumentException(); } if (anchorPoint.Buffer != HexView.Buffer) { throw new ArgumentException(); } if (anchorPoint == activePoint) { Clear(); return; } ActivationTracksFocus = true; if (alignPoints && HexView.Caret.Position.Position.ActiveColumn == HexColumnType.Values) { var bufferLines = HexView.BufferLines; if (bufferLines.BytesPerValue != 1) { Debug.Assert(anchorPoint != activePoint); if (anchorPoint < activePoint) { var anchorCell = GetCell(bufferLines, anchorPoint); var activeCell = GetCell(bufferLines, activePoint - 1); if (anchorCell != null && activeCell != null) { anchorPoint = anchorCell.BufferStart; activePoint = activeCell.BufferEnd; } } else { var activeCell = GetCell(bufferLines, activePoint); var anchorCell = GetCell(bufferLines, anchorPoint - 1); if (anchorCell != null && activeCell != null) { activePoint = activeCell.BufferStart; anchorPoint = anchorCell.BufferEnd; } } } } bool sameSelection = this.anchorPoint == anchorPoint && this.activePoint == activePoint; if (!sameSelection) { this.anchorPoint = anchorPoint; this.activePoint = activePoint; SelectionChanged?.Invoke(this, EventArgs.Empty); } }
public HexFormattedLine FindFormattedLineByBufferPosition(HexBufferPoint point) { if (isDisposed) throw new ObjectDisposedException(nameof(PhysicalLineCache)); for (int i = 0; i < cache.Count; i++) { var physLine = cache[i]; var line = physLine.FindFormattedLineByBufferPosition(point); if (line != null) return line; } return null; }
HexCellPosition CreateValuesCellPosition(HexBufferPoint position) { var line = hexView.BufferLines.GetLineFromPosition(position); var cell = line.ValueCells.GetCell(position); if (cell == null) { return(new HexCellPosition(HexColumnType.Values, position, 0)); } return(new HexCellPosition(HexColumnType.Values, cell.BufferStart, 0)); }
public bool Contains(HexBufferPoint point) { if (disposed) throw new ObjectDisposedException(nameof(PhysicalLine)); if (point.Buffer != BufferSpan.Buffer) throw new ArgumentException(); if (point < BufferSpan.Start) return false; if (IsLastLine) return point <= BufferSpan.End; return point < BufferSpan.End; }
static HexCell GetCell(HexBufferLineFormatter bufferLines, HexBufferPoint position) { var line = bufferLines.GetLineFromPosition(position); var cell = line.ValueCells.GetCell(position); if (cell == null && position == line.BufferEnd && position > line.BufferStart) { cell = line.ValueCells.GetCell(position - 1); } return(cell); }
public override void Clear() { bool isEmpty = IsEmpty; ActivationTracksFocus = true; anchorPoint = activePoint; if (!isEmpty) { SelectionChanged?.Invoke(this, EventArgs.Empty); } }
HexCellPosition CreateValuePositionLastCellCharacter(HexBufferPoint position) { var line = hexView.BufferLines.GetLineFromPosition(position); var cell = line.ValueCells.GetCell(position); if (cell == null) { return(new HexCellPosition(HexColumnType.Values, position, 0)); } return(new HexCellPosition(HexColumnType.Values, position, cell.CellSpan.Length - 1)); }
HexBufferPoint Filter(HexBufferPoint position) { if (position < HexView.BufferLines.BufferStart) { return(HexView.BufferLines.BufferStart); } if (position > HexView.BufferLines.BufferEnd) { return(HexView.BufferLines.BufferEnd); } return(position); }
public PositionAndData?Edit(HexBufferPoint position, int cellPosition, char c) { if (position.IsDefault) { return(null); } if ((uint)cellPosition >= (uint)FormattedLength) { return(null); } return(EditCore(position, cellPosition, c)); }
void GetSelectionOrCaretIfNoSelection(out HexBufferPoint anchorPoint, out HexBufferPoint activePoint) { if (!Selection.IsEmpty) { anchorPoint = Selection.AnchorPoint; activePoint = Selection.ActivePoint; if (anchorPoint > activePoint) anchorPoint = anchorPoint - 1; } else { anchorPoint = ActiveCaretBufferPosition; activePoint = anchorPoint; } }
public HexFormattedLine FindFormattedLineByBufferPosition(HexBufferPoint point) { if (disposed) throw new ObjectDisposedException(nameof(PhysicalLine)); if (point.Buffer != BufferSpan.Buffer) throw new ArgumentException(); if (!Contains(point)) return null; foreach (var line in Lines) { if (point <= line.BufferStart || line.ContainsBufferPosition(point)) return line; } return Lines[Lines.Length - 1]; }
void GetSelectionOrCaretIfNoSelection(out HexBufferPoint start, out HexBufferPoint end) { if (!wpfHexView.Selection.IsEmpty) { start = wpfHexView.Selection.Start; end = wpfHexView.Selection.End; } else { start = wpfHexView.Caret.Position.Position.ActivePosition.BufferPosition; end = start; } }
bool MoveTo(HexBufferPoint start, HexBufferPoint end, HexBufferPoint caret) { if (!HexView.BufferLines.IsValidPosition(start) || !HexView.BufferLines.IsValidPosition(end) || !HexView.BufferLines.IsValidPosition(caret)) { return(false); } HexView.Caret.MoveTo(caret); var flags = HexView.Caret.Position.Position.ActiveColumn == HexColumnType.Values ? HexSpanSelectionFlags.Values : HexSpanSelectionFlags.Ascii; var span = start <= end ? new HexBufferSpan(start, end) : new HexBufferSpan(end, start); HexView.ViewScroller.EnsureSpanVisible(span, flags, VSTE.EnsureSpanVisibleOptions.ShowStart); HexView.Selection.Clear(); return(true); }
public override double GetCoordinateAtBufferPosition(HexBufferPoint bufferPosition) { if (bufferPosition.IsDefault) { throw new ArgumentException(); } if (bufferPosition.Buffer != HexView.Buffer) { throw new ArgumentException(); } if (!HexView.BufferLines.IsValidPosition(bufferPosition)) { throw new ArgumentOutOfRangeException(nameof(bufferPosition)); } return(Start + HexView.BufferLines.GetLineNumberFromPosition(bufferPosition).ToUInt64()); }
public HexFormattedLine FindFormattedLineByBufferPosition(HexBufferPoint point) { if (isDisposed) { throw new ObjectDisposedException(nameof(PhysicalLineCache)); } for (int i = 0; i < cache.Count; i++) { var physLine = cache[i]; var line = physLine.FindFormattedLineByBufferPosition(point); if (line != null) { return(line); } } return(null); }
void InitializeState(HexViewUIState state) { if (IsValid(state)) { HexView.Options.SetOptionValue(DefaultHexViewOptions.ShowOffsetColumnId, state.ShowOffsetColumn); HexView.Options.SetOptionValue(DefaultHexViewOptions.ShowValuesColumnId, state.ShowValuesColumn); HexView.Options.SetOptionValue(DefaultHexViewOptions.ShowAsciiColumnId, state.ShowAsciiColumn); HexView.Options.SetOptionValue(DefaultHexViewOptions.StartPositionId, state.StartPosition); HexView.Options.SetOptionValue(DefaultHexViewOptions.EndPositionId, state.EndPosition); HexView.Options.SetOptionValue(DefaultHexViewOptions.BasePositionId, state.BasePosition); HexView.Options.SetOptionValue(DefaultHexViewOptions.UseRelativePositionsId, state.UseRelativePositions); HexView.Options.SetOptionValue(DefaultHexViewOptions.OffsetBitSizeId, state.OffsetBitSize); HexView.Options.SetOptionValue(DefaultHexViewOptions.HexValuesDisplayFormatId, state.HexValuesDisplayFormat); HexView.Options.SetOptionValue(DefaultHexViewOptions.BytesPerLineId, state.BytesPerLine); HexView.ViewportLeft = state.ViewportLeft; HexView.DisplayHexLineContainingBufferPosition(new HexBufferPoint(HexView.Buffer, state.TopLinePosition), state.TopLineVerticalDistance, VSTE.ViewRelativePosition.Top, null, null, DisplayHexLineOptions.CanRecreateBufferLines); var valuesPos = new HexCellPosition(HexColumnType.Values, new HexBufferPoint(HexView.Buffer, state.ValuesPosition), state.ValuesCellPosition); var asciiPos = new HexCellPosition(HexColumnType.Ascii, new HexBufferPoint(HexView.Buffer, state.AsciiPosition), 0); var newPos = new HexColumnPosition(state.ActiveColumn, valuesPos, asciiPos); // BufferLines could've been recreated, re-verify the new position if (HexView.BufferLines.IsValidPosition(newPos.ValuePosition.BufferPosition) && HexView.BufferLines.IsValidPosition(newPos.AsciiPosition.BufferPosition)) { HexView.Caret.MoveTo(newPos); } var anchorPoint = new HexBufferPoint(HexView.Buffer, state.AnchorPoint); var activePoint = new HexBufferPoint(HexView.Buffer, state.ActivePoint); if (HexView.BufferLines.IsValidPosition(anchorPoint) && HexView.BufferLines.IsValidPosition(activePoint)) { HexView.Selection.Select(anchorPoint, activePoint, alignPoints: false); } else { HexView.Selection.Clear(); } } else { HexView.Caret.MoveTo(HexView.BufferLines.BufferStart); HexView.Selection.Clear(); } }
public override WpfHexViewLine GetWpfHexViewLineContainingBufferPosition(HexBufferPoint bufferPosition) { if (!IsValid) { throw new ObjectDisposedException(nameof(WpfHexViewLineCollectionImpl)); } if (bufferPosition.Buffer != hexView.Buffer) { throw new ArgumentException(); } foreach (var line in lines) { if (line.ContainsBufferPosition(bufferPosition)) { return(line); } } return(null); }
PhysicalLine GetPhysicalLine(HexBufferPoint point) { foreach (var line in oldLines) { if (line.Contains(point)) { return(line); } } var result = CreatePhysicalLineNoCache(bufferLines, formattedLineSource, point); foreach (var line in result.Lines) { toPhysicalLine[line] = result; } oldLines.Add(result); return(result); }
public override HexToolTipInfoCollection GetToolTipInfo(HexBufferPoint position) { if (position.IsDefault) { throw new ArgumentException(); } if (position > HexPosition.MaxEndPosition) { throw new ArgumentOutOfRangeException(nameof(position)); } if (hexView.IsClosed) { return(null); } if (position >= HexPosition.MaxEndPosition) { return(null); } return(TryCreateToolTipInfoCollection(position, tagAggregator.GetTags(new HexBufferSpan(position, 1)).ToArray())); }
public override bool ContainsBufferPosition(HexBufferPoint bufferPosition) { if (!IsValid) { throw new ObjectDisposedException(nameof(WpfHexViewLineCollectionImpl)); } if (bufferPosition.Buffer != hexView.Buffer) { throw new ArgumentException(); } if (FormattedSpan.Contains(bufferPosition)) { return(true); } if (lines.Count > 0 && lines[lines.Count - 1].ContainsBufferPosition(bufferPosition)) { return(true); } return(false); }
public override bool ContainsBufferPosition(HexBufferPoint bufferPosition) { if (!IsValid) { throw new ObjectDisposedException(nameof(HexFormattedLineImpl)); } if (bufferPosition.Buffer != Buffer) { throw new ArgumentException(); } if (!(BufferStart <= bufferPosition)) { return(false); } if (IsLastVisualLine) { return(bufferPosition <= BufferEnd); } return(bufferPosition < BufferEnd); }
public bool Contains(HexBufferPoint point) { if (disposed) { throw new ObjectDisposedException(nameof(PhysicalLine)); } if (point.Buffer != BufferSpan.Buffer) { throw new ArgumentException(); } if (point < BufferSpan.Start) { return(false); } if (IsLastLine) { return(point <= BufferSpan.End); } return(point < BufferSpan.End); }
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)); }
public override void GoToPosition() { var curr = HexView.BufferLines.ToLogicalPosition(HexView.Caret.Position.Position.ActivePosition.BufferPosition); var minPos = HexView.BufferLines.ToLogicalPosition(HexView.BufferLines.StartPosition); var maxPos = HexView.BufferLines.ToLogicalPosition(HexView.BufferLines.EndPosition); if (HexView.BufferLines.BufferSpan.IsEmpty) { } else if (maxPos == HexPosition.Zero) { maxPos = HexPosition.MaxEndPosition - 1; } else { maxPos = maxPos - 1; } var data = new GoToPositionVM(curr, minPos, maxPos); var win = new GoToPositionDlg(); win.DataContext = data; win.Owner = OwnerWindow; if (HexView.Buffer.IsMemory) { win.Title = dnSpy_Resources.GoToOffset_Title_Address; win.offsetLabel.Content = dnSpy_Resources.GoToOffset_Address_Label; } else { win.Title = dnSpy_Resources.GoToOffset_Title; win.offsetLabel.Content = dnSpy_Resources.GoToOffset_Offset_Label; } if (win.ShowDialog() != true) { return; } var newPos = new HexBufferPoint(HexView.Buffer, HexView.BufferLines.ToPhysicalPosition(data.OffsetVM.Value)); MoveTo(newPos, newPos, newPos); }
protected PositionAndData?EditBit(HexBufferPoint position, int cellPosition, char c) { int newBit = ConvertFromBitCharacter(c); if (newBit < 0) { return(null); } var dataPos = position.Position + cellPosition / 8; if (dataPos >= HexPosition.MaxEndPosition) { return(null); } int bitNo = (8 - (cellPosition & 7) - 1) & 7; var newData = new byte[1]; newData[0] = position.Buffer.ReadByte(dataPos); newData[0] = (byte)((newData[0] & ~(1 << bitNo)) | (newBit << bitNo)); return(new PositionAndData(new HexBufferPoint(position.Buffer, dataPos), newData)); }
public HexFormattedLine?FindFormattedLineByBufferPosition(HexBufferPoint point) { if (disposed) { throw new ObjectDisposedException(nameof(PhysicalLine)); } if (point.Buffer != BufferSpan.Buffer) { throw new ArgumentException(); } if (!Contains(point)) { return(null); } foreach (var line in Lines) { if (point <= line.BufferStart || line.ContainsBufferPosition(point)) { return(line); } } return(Lines[Lines.Length - 1]); }
protected override PositionAndData? EditCore(HexBufferPoint position, int cellPosition, char c) => EditBit(position, cellPosition, c);
protected override PositionAndData? EditCore(HexBufferPoint position, int cellPosition, char c) => EditSignedHexBigEndian(position, cellPosition, c);
public override HexBufferLine GetLineFromPosition(HexBufferPoint position) { position = FilterAndVerify(position); ResetBuilderFields(); var linePosition = startPosition + (position.Position - startPosition).ToUInt64() / bytesPerLine * bytesPerLine; var lineEnd = HexPosition.Min(linePosition + bytesPerLine, endPosition); var lineSpan = HexSpan.FromBounds(linePosition, lineEnd); var logicalOffset = ToLogicalPosition(lineSpan.Start); var hexBytes = buffer.ReadHexBytes(lineSpan.Start, (long)lineSpan.Length.ToUInt64()); var offsetSpan = default(VST.Span); var fullValuesSpan = default(VST.Span); var visibleValuesSpan = default(VST.Span); var fullAsciiSpan = default(VST.Span); var visibleAsciiSpan = default(VST.Span); var valueCells = Array.Empty<HexCell>(); var asciiCells = Array.Empty<HexCell>(); bool needSep = false; foreach (var column in columnOrder) { switch (column) { case HexColumnType.Offset: if (showOffset) { if (needSep) stringBuilder.Append(' '); needSep = true; WriteOffset(logicalOffset, out offsetSpan); } break; case HexColumnType.Values: if (showValues) { if (needSep) stringBuilder.Append(' '); needSep = true; valueCells = WriteValues(hexBytes, lineSpan, out fullValuesSpan, out visibleValuesSpan); } break; case HexColumnType.Ascii: if (showAscii) { if (needSep) stringBuilder.Append(' '); needSep = true; asciiCells = WriteAscii(hexBytes, lineSpan, out fullAsciiSpan, out visibleAsciiSpan); } break; default: throw new InvalidOperationException(); } } var text = stringBuilder.ToString(); if (text.Length != CharsPerLine) throw new InvalidOperationException(); var valueCellColl = valueCells.Length == 0 ? HexCellCollection.Empty : new HexCellCollection(valueCells); var asciiCellColl = asciiCells.Length == 0 ? HexCellCollection.Empty : new HexCellCollection(asciiCells); var lineNumber = GetLineNumberFromPosition(new HexBufferPoint(Buffer, lineSpan.Start)); var res = new HexBufferLineImpl(this, lineNumber, columnOrder, new HexBufferSpan(buffer, lineSpan), hexBytes, text, showOffset, showValues, showAscii, logicalOffset, valueCellColl, asciiCellColl, offsetSpan, fullValuesSpan, visibleValuesSpan, fullAsciiSpan, visibleAsciiSpan); ResetBuilderFields(); return res; }
protected PositionAndData? EditBit(HexBufferPoint position, int cellPosition, char c) { int newBit = ConvertFromBitCharacter(c); if (newBit < 0) return null; var dataPos = position.Position + cellPosition / 8; if (dataPos >= HexPosition.MaxEndPosition) return null; int bitNo = (8 - (cellPosition & 7) - 1) & 7; var newData = new byte[1]; newData[0] = position.Buffer.ReadByte(dataPos); newData[0] = (byte)((newData[0] & ~(1 << bitNo)) | (newBit << bitNo)); return new PositionAndData(new HexBufferPoint(position.Buffer, dataPos), newData); }
public override void DisplayHexLineContainingBufferPosition(HexBufferPoint bufferPosition, double verticalDistance, VSTE.ViewRelativePosition relativeTo, double? viewportWidthOverride, double? viewportHeightOverride, DisplayHexLineOptions options) => DisplayLines(bufferPosition, verticalDistance, relativeTo, viewportWidthOverride ?? ViewportWidth, viewportHeightOverride ?? ViewportHeight, options, null);
PhysicalLine CreatePhysicalLineNoCache(HexBufferPoint bufferPosition, double viewportWidthOverride) { if (bufferPosition.Buffer != Buffer) throw new ArgumentException(); if (formattedLineSourceIsInvalidated) CreateFormattedLineSource(viewportWidthOverride); return CreatePhysicalLineNoCache(BufferLines, FormattedLineSource, bufferPosition); }
/// <summary> /// Displays a line in the view /// </summary> /// <param name="bufferPosition">Position</param> /// <param name="verticalDistance">Distance relative to the top or bottom of the view</param> /// <param name="relativeTo">The <see cref="VSTE.ViewRelativePosition"/></param> /// <param name="viewportWidthOverride">Overrides viewport width</param> /// <param name="viewportHeightOverride">Overrides viewport height</param> /// <param name="options">Options</param> public abstract void DisplayHexLineContainingBufferPosition(HexBufferPoint bufferPosition, double verticalDistance, VSTE.ViewRelativePosition relativeTo, double? viewportWidthOverride, double? viewportHeightOverride, DisplayHexLineOptions options);
/// <summary> /// Gets the fraction of the vertical extent of the view that corresponds to the specified buffer position /// </summary> /// <param name="bufferPosition">Buffer position</param> /// <returns></returns> public abstract double GetFractionAtBufferPosition(HexBufferPoint bufferPosition);
/// <summary> /// Extend selection /// </summary> /// <param name="newEnd">New end position</param> public abstract void ExtendSelection(HexBufferPoint newEnd);
/// <summary> /// Gets the line containing <paramref name="bufferPosition"/> /// </summary> /// <param name="bufferPosition">Buffer position</param> /// <returns></returns> public abstract WpfHexViewLine GetWpfHexViewLineContainingBufferPosition(HexBufferPoint bufferPosition);
public override HexViewLine GetHexViewLineContainingBufferPosition(HexBufferPoint bufferPosition) => GetWpfHexViewLineContainingBufferPosition(bufferPosition);
/// <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);
public override WpfHexViewLine GetWpfHexViewLineContainingBufferPosition(HexBufferPoint bufferPosition) { if (IsClosed) throw new InvalidOperationException(); if (bufferPosition.Buffer != Buffer) throw new ArgumentException(); foreach (var pline in visiblePhysicalLines) { var lline = pline.FindFormattedLineByBufferPosition(bufferPosition); if (lline != null) return lline; } var cachedLine = physicalLineCache.FindFormattedLineByBufferPosition(bufferPosition); if (cachedLine != null) return cachedLine; var physLine = CreatePhysicalLineNoCache(bufferPosition, ViewportWidth); physicalLineCache.Add(physLine); var line = physLine.FindFormattedLineByBufferPosition(bufferPosition); if (line == null) throw new InvalidOperationException(); return line; }
public abstract HexToolTipInfoCollection GetToolTipInfo(HexBufferPoint position);
static PhysicalLine CreatePhysicalLineNoCache(HexBufferLineFormatter bufferLines, HexFormattedLineSource formattedLineSource, HexBufferPoint bufferPosition) { var bufferLine = bufferLines.GetLineFromPosition(bufferPosition); var formattedLine = formattedLineSource.FormatLineInVisualBuffer(bufferLine); return new PhysicalLine(new[] { formattedLine }); }
void DisplayLines(HexBufferPoint bufferPosition, double verticalDistance, VSTE.ViewRelativePosition relativeTo, double viewportWidthOverride, double viewportHeightOverride, DisplayHexLineOptions options, double? newViewportTop) { if (IsClosed) throw new InvalidOperationException(); var oldBufferLines = hexBufferLineFormatter; var oldHexBufferLineFormatterOptions = hexBufferLineFormatterOptions; Debug.Assert(oldBufferLines != null); bool raiseBufferLinesChangedEvent = false; bool revalidateBufferPosition = false; canvas.Dispatcher.VerifyAccess(); if (bufferPosition.Buffer != Buffer) throw new ArgumentException(); if (relativeTo != VSTE.ViewRelativePosition.Top && relativeTo != VSTE.ViewRelativePosition.Bottom) throw new ArgumentOutOfRangeException(nameof(relativeTo)); if (viewportHeightOverride < 0 || double.IsNaN(viewportHeightOverride)) throw new ArgumentOutOfRangeException(nameof(viewportHeightOverride)); if (viewportWidthOverride < 0 || double.IsNaN(viewportWidthOverride)) throw new ArgumentOutOfRangeException(nameof(viewportWidthOverride)); bool invalidateAllLines = false; if (recreateHexBufferLineFormatter) invalidateAllLines = true; if (viewportWidthOverride != lastViewportWidth || viewportWidthOverride != lastFormattedLineSourceViewportWidth) { invalidateAllLines = true; lastViewportWidth = viewportWidthOverride; } // Make sure the scheduled method doesn't try to call this method delayLayoutLinesInProgress = false; if (invalidateAllLines) { invalidatedRegions.Clear(); invalidatedRegions.Add(new HexBufferSpan(new HexBufferPoint(Buffer, 0), new HexBufferPoint(Buffer, HexPosition.MaxEndPosition))); } var regionsToInvalidate = new NormalizedHexBufferSpanCollection(invalidatedRegions); invalidatedRegions.Clear(); if (invalidatedRegions.Capacity > 100) invalidatedRegions.TrimExcess(); if (invalidateAllLines || formattedLineSourceIsInvalidated) { CreateFormattedLineSource(viewportWidthOverride); formattedLineSourceIsInvalidated = false; recreateHexBufferLineFormatter = true; } // This one depends on FormattedLineSource and must be created afterwards if (recreateHexBufferLineFormatter) { recreateHexBufferLineFormatter = false; raiseBufferLinesChangedEvent = true; if ((options & DisplayHexLineOptions.CanRecreateBufferLines) != 0) { // It's safe to invalidate it here since we were called by the dispatcher and // not by user code. hexBufferLineFormatter = null; // Once the new instance gets created, the input bufferPosition could be invalid // because start and/or end got updated. Re-validate it before creating new lines. revalidateBufferPosition = true; } else { // Don't re-create it here. That can lead to exceptions if Start/End positions get // updated and bufferPosition becomes invalid. New BufferLines' IsValidPosition() throws. // It's recreated with a short delay after raising LayoutChanged. } } var lineTransformProvider = LineTransformProvider; if (InLayout) throw new InvalidOperationException(); inLayout = true; var oldVisibleLines = new HashSet<HexViewLine>(wpfHexViewLineCollection == null ? (IEnumerable<HexViewLine>)Array.Empty<HexViewLine>() : wpfHexViewLineCollection); wpfHexViewLineCollection?.Invalidate(); var layoutHelper = new LayoutHelper(BufferLines, lineTransformProvider, newViewportTop ?? 0, oldVisibleLines, GetValidCachedLines(regionsToInvalidate), FormattedLineSource); if (revalidateBufferPosition) { if (bufferPosition < BufferLines.BufferStart) { bufferPosition = BufferLines.BufferStart; relativeTo = VSTE.ViewRelativePosition.Top; verticalDistance = 0; } else if (bufferPosition > BufferLines.BufferEnd) { bufferPosition = BufferLines.BufferEnd; relativeTo = VSTE.ViewRelativePosition.Bottom; verticalDistance = 0; } } layoutHelper.LayoutLines(bufferPosition, relativeTo, verticalDistance, ViewportLeft, viewportWidthOverride, viewportHeightOverride); visiblePhysicalLines.AddRange(layoutHelper.AllVisiblePhysicalLines); wpfHexViewLineCollection = new WpfHexViewLineCollectionImpl(this, layoutHelper.AllVisibleLines); if (!InLayout) throw new InvalidOperationException(); inLayout = false; textLayer.AddVisibleLines(layoutHelper.AllVisibleLines); var newOrReformattedLines = layoutHelper.NewOrReformattedLines.ToArray(); var translatedLines = layoutHelper.TranslatedLines.ToArray(); if (layoutHelper.NewViewportTop != viewportTop) { viewportTop = layoutHelper.NewViewportTop; Canvas.SetTop(normalAdornmentLayerCollection, -viewportTop); } if ((options & DisplayHexLineOptions.CanRecreateBufferLines) != 0) { if (raiseBufferLinesChangedEvent) RaiseBufferLinesChanged(oldBufferLines); } else if (raiseBufferLinesChangedEvent && oldBufferLines == hexBufferLineFormatter) { var newOptions = GetHexBufferLineFormatterOptions(); if (!newOptions.Equals(oldHexBufferLineFormatterOptions)) { canvas.Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() => { if (oldBufferLines == hexBufferLineFormatter) { hexBufferLineFormatter = null; var newBufferLines = BufferLines; RaiseBufferLinesChanged(oldBufferLines); var line = wpfHexViewLineCollection.FirstVisibleLine; verticalDistance = line.Top - ViewportTop; bufferPosition = line.BufferStart; if (bufferPosition < BufferLines.BufferStart) bufferPosition = BufferLines.BufferStart; else if (bufferPosition > BufferLines.BufferEnd) bufferPosition = BufferLines.BufferEnd; DisplayLines(bufferPosition, verticalDistance, VSTE.ViewRelativePosition.Top, ViewportWidth, ViewportHeight, DisplayHexLineOptions.CanRecreateBufferLines, ViewportTop); } })); } } // Raise this event after BufferLinesChanged event. BufferLinesChanged is more low level and // various code could use cached positions in LayoutChanged handlers (eg. the caret will use // its cached position). If this event is raised afterwards, they have a chance to re-validate // their cached values. RaiseLayoutChanged(viewportWidthOverride, viewportHeightOverride, newOrReformattedLines, translatedLines); }
public override double GetFractionAtBufferPosition(HexBufferPoint bufferPosition) { if (bufferPosition.IsDefault) throw new ArgumentException(); if (bufferPosition.Buffer != HexView.Buffer) throw new ArgumentException(); if (!HexView.BufferLines.IsValidPosition(bufferPosition)) throw new ArgumentOutOfRangeException(nameof(bufferPosition)); double length = End - Start; if (length == 0) return 0; if (HexView.BufferLines.GetLineNumberFromPosition(bufferPosition) + 1 == HexView.BufferLines.LineCount) return 1; var coord = GetCoordinateAtBufferPosition(bufferPosition); Debug.Assert(Start <= coord && coord <= End); return Math.Min(Math.Max(0, (coord - Start) / length), 1); }
/// <summary> /// Displays a line in the view /// </summary> /// <param name="bufferPosition">Position</param> /// <param name="verticalDistance">Distance relative to the top or bottom of the view</param> /// <param name="relativeTo">The <see cref="VSTE.ViewRelativePosition"/></param> /// <param name="viewportWidthOverride">Overrides viewport width</param> /// <param name="viewportHeightOverride">Overrides viewport height</param> public void DisplayHexLineContainingBufferPosition(HexBufferPoint bufferPosition, double verticalDistance, VSTE.ViewRelativePosition relativeTo, double? viewportWidthOverride, double? viewportHeightOverride) => DisplayHexLineContainingBufferPosition(bufferPosition, verticalDistance, relativeTo, viewportWidthOverride, viewportHeightOverride, DisplayHexLineOptions.None);
public override HexPosition GetLineNumberFromPosition(HexBufferPoint position) { position = FilterAndVerify(position); return (position.Position - startPosition).ToUInt64() / bytesPerLine; }
/// <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);
/// <summary> /// Select a span /// </summary> /// <param name="anchorPoint">Anchor point</param> /// <param name="activePoint">Active point</param> /// <param name="alignPoints">true to align the span to include all bytes of the cells</param> public abstract void Select(HexBufferPoint anchorPoint, HexBufferPoint activePoint, bool alignPoints);
/// <summary> /// Displays a line in the view /// </summary> /// <param name="bufferPosition">Position</param> /// <param name="verticalDistance">Distance relative to the top or bottom of the view</param> /// <param name="relativeTo">The <see cref="VSTE.ViewRelativePosition"/></param> public void DisplayHexLineContainingBufferPosition(HexBufferPoint bufferPosition, double verticalDistance, VSTE.ViewRelativePosition relativeTo) => DisplayHexLineContainingBufferPosition(bufferPosition, verticalDistance, relativeTo, null, null, DisplayHexLineOptions.None);
/// <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);
/// <summary> /// Gets the line that contains the position /// </summary> /// <param name="bufferPosition">Position</param> /// <returns></returns> public abstract WpfHexViewLine GetWpfHexViewLineContainingBufferPosition(HexBufferPoint bufferPosition);
/// <summary> /// Returns true if <paramref name="bufferPosition"/> lies within this line /// </summary> /// <param name="bufferPosition">Position</param> /// <returns></returns> public abstract bool ContainsBufferPosition(HexBufferPoint bufferPosition);