public override void EnsureVisible() { if (!IsValuesCaretPresent && !IsAsciiCaretPresent) { return; } var line = ContainingHexViewLine; if (line.VisibilityState != VSTF.VisibilityState.FullyVisible) { VSTE.ViewRelativePosition relativeTo; var firstVisibleLine = hexView.HexViewLines?.FirstVisibleLine; if (firstVisibleLine == null || !firstVisibleLine.IsVisible()) { relativeTo = VSTE.ViewRelativePosition.Top; } else if (line.BufferStart <= firstVisibleLine.BufferStart) { relativeTo = VSTE.ViewRelativePosition.Top; } else { relativeTo = VSTE.ViewRelativePosition.Bottom; } hexView.DisplayHexLineContainingBufferPosition(line.BufferStart, 0, relativeTo); } double left, right, width; switch (currentPosition.ActiveColumn) { case HexColumnType.Values: left = hexCaretLayer.ValuesLeft; right = hexCaretLayer.ValuesRight; width = hexCaretLayer.ValuesWidth; break; case HexColumnType.Ascii: left = hexCaretLayer.AsciiLeft; right = hexCaretLayer.AsciiRight; width = hexCaretLayer.AsciiWidth; break; case HexColumnType.Offset: default: throw new InvalidOperationException(); } double availWidth = Math.Max(0, hexView.ViewportWidth - width); double extraScroll; if (availWidth >= WpfHexViewConstants.EXTRA_HORIZONTAL_WIDTH) { extraScroll = WpfHexViewConstants.EXTRA_HORIZONTAL_WIDTH; } else { extraScroll = availWidth / 2; } if (hexView.ViewportWidth == 0) { // Don't do anything if there's zero width. This can happen during // startup when code accesses the caret before the window is shown. } else if (left < hexView.ViewportLeft) { hexView.ViewportLeft = left - extraScroll; } else if (right > hexView.ViewportRight) { hexView.ViewportLeft = right + extraScroll - hexView.ViewportWidth; } }
void OnScroll(ScrollDirection value, double xCoordinate) { HexViewLine line; HexBufferPoint lineStart; switch (value) { case ScrollDirection.Left: line = wpfHexView.Caret.ContainingHexViewLine; if (line.TextLeft >= wpfHexView.ViewportLeft) { StopScrolling(); } else if (wpfHexView.Caret.Position.Position.ActivePosition.BufferPosition != line.BufferStart) { editorOperations.MoveToPreviousCharacter(true); } else { wpfHexView.ViewportLeft = line.TextLeft; StopScrolling(); } break; case ScrollDirection.Right: line = wpfHexView.Caret.ContainingHexViewLine; if (line.TextRight <= wpfHexView.ViewportRight) { StopScrolling(); } else if (wpfHexView.Caret.Position.Position.ActivePosition.BufferPosition < line.BufferEnd) { editorOperations.MoveToNextCharacter(true); } else { wpfHexView.ViewportLeft = Math.Max(0, line.TextRight - wpfHexView.ViewportWidth); StopScrolling(); } break; case ScrollDirection.Up: line = wpfHexView.HexViewLines.FirstVisibleLine; if (line.VisibilityState == VSTF.VisibilityState.FullyVisible && !line.IsFirstDocumentLine()) { line = wpfHexView.GetHexViewLineContainingBufferPosition(line.BufferStart - 1); } lineStart = line.BufferStart; if (line.VisibilityState != VSTF.VisibilityState.FullyVisible) { wpfHexView.DisplayHexLineContainingBufferPosition(line.BufferStart, 0, VSTE.ViewRelativePosition.Top); } if (!line.IsValid) { line = wpfHexView.GetHexViewLineContainingBufferPosition(lineStart); } if (line.IsFirstDocumentLine()) { StopScrolling(); } editorOperations.MoveCaret(line, xCoordinate, true, hexMoveToFlags); break; case ScrollDirection.Down: line = wpfHexView.HexViewLines.LastVisibleLine; if (line.VisibilityState == VSTF.VisibilityState.FullyVisible && !line.IsLastDocumentLine()) { line = wpfHexView.GetHexViewLineContainingBufferPosition(line.BufferEnd); } lineStart = line.BufferStart; if (line.VisibilityState != VSTF.VisibilityState.FullyVisible) { wpfHexView.DisplayHexLineContainingBufferPosition(line.BufferStart, 0, VSTE.ViewRelativePosition.Bottom); } if (!line.IsValid) { line = wpfHexView.GetHexViewLineContainingBufferPosition(lineStart); } if (line.IsLastDocumentLine()) { StopScrolling(); } editorOperations.MoveCaret(line, xCoordinate, true, hexMoveToFlags); break; default: throw new ArgumentOutOfRangeException(nameof(value)); } wpfHexView.Caret.EnsureVisible(); }