/// <summary> /// Scrolls the viewport one line up or down /// </summary> /// <param name="direction">Direction</param> public void ScrollViewportVerticallyByLine(VSTE.ScrollDirection direction) => ScrollViewportVerticallyByLines(direction, 1);
/// <summary> /// Scrolls the viewport one page up or down /// </summary> /// <param name="direction">Direction</param> /// <returns></returns> public abstract bool ScrollViewportVerticallyByPage(VSTE.ScrollDirection direction);
public override bool ScrollViewportVerticallyByPage(VSTE.ScrollDirection direction) { bool hasFullyVisibleLines = hexView.HexViewLines.Any(a => a.VisibilityState == VSTF.VisibilityState.FullyVisible); if (direction == VSTE.ScrollDirection.Up) { var firstVisibleLine = hexView.HexViewLines.FirstVisibleLine; if (firstVisibleLine.Height > hexView.ViewportHeight) { ScrollViewportVerticallyByPixels(hexView.ViewportHeight); return(hasFullyVisibleLines); } double top; if (firstVisibleLine.VisibilityState == VSTF.VisibilityState.FullyVisible) { if (firstVisibleLine.IsFirstDocumentLine()) { return(hasFullyVisibleLines); } top = firstVisibleLine.Top; } else { top = firstVisibleLine.Bottom; // Top of next line, which is possibly not in HexViewLines so we can't use its Top prop } var line = firstVisibleLine; // Top is only valid if the line is in HexViewLines, so use this variable to track the correct line top value double lineTop = line.Top; var prevLine = line; // Cache this since prevLine could've been disposed when we need to access this property var prevLineStart = prevLine.BufferStart; while (lineTop + hexView.ViewportHeight >= top) { prevLine = line; prevLineStart = prevLine.BufferStart; if (line.IsFirstDocumentLine()) { break; } line = hexView.GetHexViewLineContainingBufferPosition(line.BufferStart - 1); if (line.VisibilityState == VSTF.VisibilityState.Unattached) { // Height is only fully initialized once it's been shown on the screen // (its LineTransform property is used to calculate Height) var lineStart = line.BufferStart; hexView.DisplayHexLineContainingBufferPosition(lineStart, 0, VSTE.ViewRelativePosition.Bottom); line = hexView.GetHexViewLineContainingBufferPosition(lineStart); Debug.Assert(line.VisibilityState != VSTF.VisibilityState.Unattached); } lineTop -= line.Height; } hexView.DisplayHexLineContainingBufferPosition(prevLineStart, 0, VSTE.ViewRelativePosition.Top); } else { Debug.Assert(direction == VSTE.ScrollDirection.Down); double pixels = hexView.ViewportHeight; var lastVisibleLine = hexView.HexViewLines.LastVisibleLine; if (lastVisibleLine.Height > hexView.ViewportHeight) { // This line intentionally left blank } else if (lastVisibleLine.VisibilityState == VSTF.VisibilityState.FullyVisible) { if (lastVisibleLine.IsLastDocumentLine()) { hexView.DisplayHexLineContainingBufferPosition(lastVisibleLine.BufferStart, 0, VSTE.ViewRelativePosition.Top); return(hasFullyVisibleLines); } } else { pixels -= hexView.ViewportBottom - lastVisibleLine.Top; } ScrollViewportVerticallyByPixels(-pixels); } return(hasFullyVisibleLines); }
/// <summary> /// Scrolls the viewport by lines /// </summary> /// <param name="direction">Direction</param> /// <param name="count">Number of lines to scroll</param> public abstract void ScrollViewportVerticallyByLines(VSTE.ScrollDirection direction, int count);
public override void ScrollViewportVerticallyByLines(VSTE.ScrollDirection direction, int count) { if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } if (direction == VSTE.ScrollDirection.Up) { double pixels = 0; var line = hexView.HexViewLines.FirstVisibleLine; for (int i = 0; i < count; i++) { if (i == 0) { if (line.VisibilityState == VSTF.VisibilityState.PartiallyVisible) { pixels += hexView.ViewportTop - line.Top; } if (line.BufferStart > hexView.BufferLines.BufferStart) { line = hexView.GetHexViewLineContainingBufferPosition(line.BufferStart - 1); pixels += line.Height; } } else { if (line.VisibilityState == VSTF.VisibilityState.Unattached) { // Height is only fully initialized once it's been shown on the screen // (its LineTransform property is used to calculate Height) var lineStart = line.BufferStart; hexView.DisplayHexLineContainingBufferPosition(lineStart, 0, VSTE.ViewRelativePosition.Top); line = hexView.GetHexViewLineContainingBufferPosition(lineStart); Debug.Assert(line.VisibilityState != VSTF.VisibilityState.Unattached); pixels = 0; } else { pixels += line.Height; } } if (line.BufferStart <= hexView.BufferLines.BufferStart) { break; } line = hexView.GetHexViewLineContainingBufferPosition(line.BufferStart - 1); } if (pixels != 0) { ScrollViewportVerticallyByPixels(pixels); } } else { Debug.Assert(direction == VSTE.ScrollDirection.Down); double pixels = 0; var line = hexView.HexViewLines.FirstVisibleLine; for (int i = 0; i < count; i++) { if (line.IsLastDocumentLine()) { break; } if (i == 0) { if (line.VisibilityState == VSTF.VisibilityState.FullyVisible) { pixels += line.Height; } else { pixels += line.Bottom - hexView.ViewportTop; line = hexView.GetHexViewLineContainingBufferPosition(line.BufferEnd); pixels += line.Height; } } else { if (line.VisibilityState == VSTF.VisibilityState.Unattached) { // Height is only fully initialized once it's been shown on the screen // (its LineTransform property is used to calculate Height) var lineStart = line.BufferStart; hexView.DisplayHexLineContainingBufferPosition(lineStart, 0, VSTE.ViewRelativePosition.Top); line = hexView.GetHexViewLineContainingBufferPosition(lineStart); Debug.Assert(line.VisibilityState != VSTF.VisibilityState.Unattached); pixels = 0; } else { pixels += line.Height; } } if (line.IsLastDocumentLine()) { break; } line = hexView.GetHexViewLineContainingBufferPosition(line.BufferEnd); } if (pixels != 0) { ScrollViewportVerticallyByPixels(-pixels); } } }