Exemplo n.º 1
0
		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);
		}
Exemplo n.º 2
0
 /// <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);
Exemplo n.º 3
0
		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);
Exemplo n.º 4
0
		/// <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);