public HexAdornmentLayerElementImpl(VSTE.AdornmentPositioningBehavior behavior, HexBufferSpan? visualSpan, object tag, UIElement adornment, VSTE.AdornmentRemovedCallback removedCallback) {
			Adornment = adornment;
			Behavior = behavior;
			RemovedCallback = removedCallback;
			Tag = tag;
			VisualSpan = visualSpan;
		}
			public override VSTF.LineTransform GetLineTransform(HexViewLine line, double yPosition, VSTE.ViewRelativePosition placement) {
				var transform = removeExtraTextLineVerticalPixels ?
					new VSTF.LineTransform(0, 0, line.DefaultLineTransform.VerticalScale, line.DefaultLineTransform.Right) :
					line.DefaultLineTransform;
				foreach (var source in lineTransformSources)
					transform = VSTF.LineTransform.Combine(transform, source.GetLineTransform(line, yPosition, placement));
				return transform;
			}
		public override bool AddAdornment(VSTE.AdornmentPositioningBehavior behavior, HexBufferSpan? visualSpan, object tag, UIElement adornment, VSTE.AdornmentRemovedCallback removedCallback) {
			if (adornment == null)
				throw new ArgumentNullException(nameof(adornment));
			if (visualSpan != null && visualSpan.Value.IsDefault)
				throw new ArgumentException();
			if (visualSpan == null && behavior == VSTE.AdornmentPositioningBehavior.TextRelative)
				throw new ArgumentNullException(nameof(visualSpan));
			if ((uint)behavior > (uint)VSTE.AdornmentPositioningBehavior.TextRelative)
				throw new ArgumentOutOfRangeException(nameof(behavior));
			if (layerKind != HexLayerKind.Normal) {
				if (behavior != VSTE.AdornmentPositioningBehavior.OwnerControlled)
					throw new ArgumentOutOfRangeException(nameof(behavior), "Special layers must use AdornmentPositioningBehavior.OwnerControlled");
				if (visualSpan != null)
					throw new ArgumentOutOfRangeException(nameof(visualSpan), "Special layers must use a null visual span");
			}
			bool canAdd = visualSpan == null || HexView.HexViewLines.IntersectsBufferSpan(visualSpan.Value);
			if (canAdd) {
				var layerElem = new HexAdornmentLayerElementImpl(behavior, visualSpan, tag, adornment, removedCallback);
				canvas.Children.Add(layerElem.Adornment);
				adornmentLayerElements.Add(layerElem);
			}
			return canAdd;
		}
		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);
		}
Beispiel #5
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);
Beispiel #6
0
#pragma warning restore 0169

		public WpfHexViewImpl(HexBuffer buffer, VSTE.ITextViewRoleSet roles, VSTE.IEditorOptions parentOptions, HexEditorOptionsFactoryService hexEditorOptionsFactoryService, ICommandService commandService, FormattedHexSourceFactoryService formattedHexSourceFactoryService, HexViewClassifierAggregatorService hexViewClassifierAggregatorService, HexAndAdornmentSequencerFactoryService hexAndAdornmentSequencerFactoryService, HexBufferLineFormatterFactoryService bufferLineProviderFactoryService, HexClassificationFormatMapService classificationFormatMapService, HexEditorFormatMapService editorFormatMapService, HexAdornmentLayerDefinitionService adornmentLayerDefinitionService, HexLineTransformProviderService lineTransformProviderService, HexSpaceReservationStackProvider spaceReservationStackProvider, Lazy<WpfHexViewCreationListener, IDeferrableTextViewRoleMetadata>[] wpfHexViewCreationListeners, VSTC.IClassificationTypeRegistryService classificationTypeRegistryService, Lazy<HexCursorProviderFactory, ITextViewRoleMetadata>[] hexCursorProviderFactories) {
			if (buffer == null)
				throw new ArgumentNullException(nameof(buffer));
			if (roles == null)
				throw new ArgumentNullException(nameof(roles));
			if (parentOptions == null)
				throw new ArgumentNullException(nameof(parentOptions));
			if (hexEditorOptionsFactoryService == null)
				throw new ArgumentNullException(nameof(hexEditorOptionsFactoryService));
			if (commandService == null)
				throw new ArgumentNullException(nameof(commandService));
			if (formattedHexSourceFactoryService == null)
				throw new ArgumentNullException(nameof(formattedHexSourceFactoryService));
			if (hexViewClassifierAggregatorService == null)
				throw new ArgumentNullException(nameof(hexViewClassifierAggregatorService));
			if (hexAndAdornmentSequencerFactoryService == null)
				throw new ArgumentNullException(nameof(hexAndAdornmentSequencerFactoryService));
			if (bufferLineProviderFactoryService == null)
				throw new ArgumentNullException(nameof(bufferLineProviderFactoryService));
			if (classificationFormatMapService == null)
				throw new ArgumentNullException(nameof(classificationFormatMapService));
			if (editorFormatMapService == null)
				throw new ArgumentNullException(nameof(editorFormatMapService));
			if (adornmentLayerDefinitionService == null)
				throw new ArgumentNullException(nameof(adornmentLayerDefinitionService));
			if (lineTransformProviderService == null)
				throw new ArgumentNullException(nameof(lineTransformProviderService));
			if (spaceReservationStackProvider == null)
				throw new ArgumentNullException(nameof(spaceReservationStackProvider));
			if (wpfHexViewCreationListeners == null)
				throw new ArgumentNullException(nameof(wpfHexViewCreationListeners));
			if (classificationTypeRegistryService == null)
				throw new ArgumentNullException(nameof(classificationTypeRegistryService));
			if (hexCursorProviderFactories == null)
				throw new ArgumentNullException(nameof(hexCursorProviderFactories));
			canvas = new HexViewCanvas(this);
			Buffer = buffer;
			thisHexLineTransformSource = new MyHexLineTransformSource(this);
			this.bufferLineProviderFactoryService = bufferLineProviderFactoryService;
			mouseHoverHelper = new MouseHoverHelper(this);
			physicalLineCache = new PhysicalLineCache(32);
			visiblePhysicalLines = new List<PhysicalLine>();
			invalidatedRegions = new List<HexBufferSpan>();
			this.formattedHexSourceFactoryService = formattedHexSourceFactoryService;
			zoomLevel = VSTE.ZoomConstants.DefaultZoom;
			DsImage.SetZoom(VisualElement, zoomLevel / 100);
			this.adornmentLayerDefinitionService = adornmentLayerDefinitionService;
			this.lineTransformProviderService = lineTransformProviderService;
			this.wpfHexViewCreationListeners = wpfHexViewCreationListeners.Where(a => roles.ContainsAny(a.Metadata.TextViewRoles)).ToArray();
			recreateLineTransformProvider = true;
			normalAdornmentLayerCollection = new HexAdornmentLayerCollection(this, HexLayerKind.Normal);
			overlayAdornmentLayerCollection = new HexAdornmentLayerCollection(this, HexLayerKind.Overlay);
			underlayAdornmentLayerCollection = new HexAdornmentLayerCollection(this, HexLayerKind.Underlay);
			canvas.IsVisibleChanged += WpfHexView_IsVisibleChanged;
			Roles = roles;
			Options = hexEditorOptionsFactoryService.GetOptions(this);
			Options.Parent = parentOptions;
			ViewScroller = new HexViewScrollerImpl(this);
			hasKeyboardFocus = canvas.IsKeyboardFocusWithin;
			oldViewState = new HexViewState(this);
			aggregateClassifier = hexViewClassifierAggregatorService.GetClassifier(this);
			hexAndAdornmentSequencer = hexAndAdornmentSequencerFactoryService.Create(this);
			classificationFormatMap = classificationFormatMapService.GetClassificationFormatMap(this);
			editorFormatMap = editorFormatMapService.GetEditorFormatMap(this);
			spaceReservationStack = spaceReservationStackProvider.Create(this);

			textLayer = new TextLayer(GetAdornmentLayer(PredefinedHexAdornmentLayers.Text));
			HexSelection = new HexSelectionImpl(this, GetAdornmentLayer(PredefinedHexAdornmentLayers.Selection), editorFormatMap);
			HexCaret = new HexCaretImpl(this, GetAdornmentLayer(PredefinedHexAdornmentLayers.Caret), classificationFormatMap, classificationTypeRegistryService);

			canvas.Children.Add(underlayAdornmentLayerCollection);
			canvas.Children.Add(normalAdornmentLayerCollection);
			canvas.Children.Add(overlayAdornmentLayerCollection);
			canvas.Focusable = true;
			canvas.FocusVisualStyle = null;
			InitializeOptions();

			Options.OptionChanged += EditorOptions_OptionChanged;
			Buffer.ChangedLowPriority += HexBuffer_ChangedLowPriority;
			Buffer.BufferSpanInvalidated += Buffer_BufferSpanInvalidated;
			aggregateClassifier.ClassificationChanged += AggregateClassifier_ClassificationChanged;
			hexAndAdornmentSequencer.SequenceChanged += HexAndAdornmentSequencer_SequenceChanged;
			classificationFormatMap.ClassificationFormatMappingChanged += ClassificationFormatMap_ClassificationFormatMappingChanged;
			editorFormatMap.FormatMappingChanged += EditorFormatMap_FormatMappingChanged;
			spaceReservationStack.GotAggregateFocus += SpaceReservationStack_GotAggregateFocus;
			spaceReservationStack.LostAggregateFocus += SpaceReservationStack_LostAggregateFocus;

			UpdateBackground();
			CreateFormattedLineSource(ViewportWidth);
			var dummy = BufferLines;
			HexSelection.Initialize();
			HexCaret.Initialize();
			InitializeZoom();
			UpdateRemoveExtraTextLineVerticalPixels();

			if (Roles.Contains(PredefinedHexViewRoles.Interactive))
				RegisteredCommandElement = commandService.Register(VisualElement, this);
			else
				RegisteredCommandElement = TE.NullRegisteredCommandElement.Instance;

			hexCursorProviderInfoCollection = new HexCursorProviderInfoCollection(CreateCursorProviders(hexCursorProviderFactories), Cursors.IBeam);
			hexCursorProviderInfoCollection.CursorChanged += HexCursorProviderInfoCollection_CursorChanged;
			canvas.Cursor = hexCursorProviderInfoCollection.Cursor;

			NotifyHexViewCreated();
		}
		public override WpfHexView Create(HexBuffer buffer, VSTE.ITextViewRoleSet roles, VSTE.IEditorOptions parentOptions, HexViewCreatorOptions options) {
			if (buffer == null)
				throw new ArgumentNullException(nameof(buffer));
			if (roles == null)
				throw new ArgumentNullException(nameof(roles));
			if (parentOptions == null)
				throw new ArgumentNullException(nameof(parentOptions));

			var wpfHexView = new WpfHexViewImpl(buffer, roles, parentOptions, hexEditorOptionsFactoryService, commandService, formattedHexSourceFactoryService, hexViewClassifierAggregatorService, hexAndAdornmentSequencerFactoryService, hexBufferLineProviderFactoryService, classificationFormatMapService, editorFormatMapService, adornmentLayerDefinitionService, lineTransformProviderService, spaceReservationStackProvider, wpfHexViewCreationListeners, classificationTypeRegistryService);

			if (options?.MenuGuid != null) {
				var guidObjectsProvider = new GuidObjectsProvider(wpfHexView, options?.CreateGuidObjects);
				menuService.InitializeContextMenu(wpfHexView.VisualElement, options.MenuGuid.Value, guidObjectsProvider, new HexContextMenuInitializer(wpfHexView));
			}

			HexViewCreated?.Invoke(this, new HexViewCreatedEventArgs(wpfHexView));
			foreach (var lz in hexEditorFactoryServiceListeners)
				lz.Value.HexViewCreated(wpfHexView);

			return wpfHexView;
		}
Beispiel #8
0
		void HexView_BackgroundBrushChanged(object sender, VSTE.BackgroundBrushChangedEventArgs e) => UpdateBackground();
Beispiel #9
0
		void HexView_ZoomLevelChanged(object sender, VSTE.ZoomLevelChangedEventArgs e) => zoomControl.UpdateTextWithZoomLevel();
		void Options_OptionChanged(object sender, VSTE.EditorOptionChangedEventArgs e) {
			if (e.OptionId == DefaultHexViewHostOptions.HorizontalScrollBarName)
				UpdateVisibility();
		}
			public void LayoutLines(HexBufferPoint bufferPosition, VSTE.ViewRelativePosition relativeTo, double verticalDistance, double viewportLeft, double viewportWidthOverride, double viewportHeightOverride) {
				NewViewportTop = requestedViewportTop;
				var infos = CreateLineInfos(bufferPosition, relativeTo, verticalDistance, viewportHeightOverride);

				// The first line of the file must always be shown at the top of the view
				if (infos[0].Y > NewViewportTop) {
					infos = CreateLineInfos(bufferLines.BufferSpan.Start, VSTE.ViewRelativePosition.Top, 0, viewportHeightOverride);
					Debug.Assert(infos[0].Y == NewViewportTop);
				}

				// Include a hidden line before the first line and one after the last line,
				// just like in VS' WpfHexViewLine collection.
				var firstInfo = infos[0];
				var prevLine = AddLineTransform(GetLineBefore(firstInfo.Line), firstInfo.Y, VSTE.ViewRelativePosition.Bottom);
				if (prevLine != null)
					infos.Insert(0, new LineInfo(prevLine, firstInfo.Y - prevLine.Height));
				var lastInfo = infos[infos.Count - 1];
				var nextLine = AddLineTransform(GetLineAfter(lastInfo.Line), lastInfo.Y + lastInfo.Line.Height, VSTE.ViewRelativePosition.Top);
				if (nextLine != null)
					infos.Add(new LineInfo(nextLine, lastInfo.Y + lastInfo.Line.Height));

				var keptLines = new HashSet<PhysicalLine>();
				foreach (var info in infos)
					keptLines.Add(toPhysicalLine[info.Line]);
				foreach (var physLine in toPhysicalLine.Values) {
					if (!keptLines.Contains(physLine))
						physLine.Dispose();
				}

				var newTop = GetNewViewportTop(infos, NewViewportTop);
				var delta = -NewViewportTop + newTop;
				NewViewportTop = newTop;
				var visibleLines = new HashSet<WpfHexViewLine>();
				var visibleArea = new Rect(viewportLeft, NewViewportTop, viewportWidthOverride, viewportHeightOverride);
				NewOrReformattedLines = new List<WpfHexViewLine>();
				TranslatedLines = new List<WpfHexViewLine>();
				AllVisibleLines = new List<WpfHexViewLine>();
				foreach (var info in infos) {
					var line = info.Line;
					visibleLines.Add(line);
					AllVisibleLines.Add(line);
					double newLineTop = delta + info.Y;
					if (!oldVisibleLines.Contains(line)) {
						line.SetChange(VSTF.TextViewLineChange.NewOrReformatted);
						line.SetDeltaY(0);
					}
					else {
						var deltaY = newLineTop - line.Top;
						line.SetDeltaY(deltaY);
						// If it got a new line transform, it will have Change == NewOrReformatted,
						// and that change has priority over Translated.
						if (deltaY != 0 && line.Change == VSTF.TextViewLineChange.None)
							line.SetChange(VSTF.TextViewLineChange.Translated);
					}
					line.SetTop(newLineTop);
					line.SetVisibleArea(visibleArea);
					if (line.Change == VSTF.TextViewLineChange.Translated)
						TranslatedLines.Add(line);
					else if (line.Change == VSTF.TextViewLineChange.NewOrReformatted)
						NewOrReformattedLines.Add(line);
				}
				bool foundVisibleLine = false;
				foreach (var info in infos) {
					if (visibleLines.Contains(info.Line)) {
						foundVisibleLine = true;
						continue;
					}
					info.Line.SetChange(VSTF.TextViewLineChange.None);
					info.Line.SetDeltaY(0);
					info.Line.SetTop(foundVisibleLine ? double.PositiveInfinity : double.NegativeInfinity);
					info.Line.SetVisibleArea(visibleArea);
				}
				Debug.Assert(NewOrReformattedLines.Count + TranslatedLines.Count <= AllVisibleLines.Count);
				Debug.Assert(AllVisibleLines.Count >= 1);
				if (AllVisibleLines.Count == 0)
					throw new InvalidOperationException();
				AllVisiblePhysicalLines = new List<PhysicalLine>(keptLines);
			}
			HexFormattedLine AddLineTransform(HexFormattedLine line, double yPosition, VSTE.ViewRelativePosition placement) {
				if (line != null) {
					var lineTransform = lineTransformProvider.GetLineTransform(line, yPosition, placement);
					if (lineTransform != line.LineTransform) {
						line.SetLineTransform(lineTransform);
						line.SetChange(VSTF.TextViewLineChange.NewOrReformatted);
					}
				}
				return line;
			}
			List<LineInfo> CreateLineInfos(HexBufferPoint bufferPosition, VSTE.ViewRelativePosition relativeTo, double verticalDistance, double viewportHeightOverride) {
				var lineInfos = new List<LineInfo>();
				var startLine = GetLine(bufferPosition);

				double newViewportBottom = NewViewportTop + viewportHeightOverride;
				double lineStartY;
				if (relativeTo == VSTE.ViewRelativePosition.Top) {
					lineStartY = NewViewportTop + verticalDistance;
					AddLineTransform(startLine, lineStartY, VSTE.ViewRelativePosition.Top);
				}
				else {
					Debug.Assert(relativeTo == VSTE.ViewRelativePosition.Bottom);
					lineStartY = NewViewportTop + viewportHeightOverride - verticalDistance;
					AddLineTransform(startLine, lineStartY, VSTE.ViewRelativePosition.Bottom);
					lineStartY -= startLine.Height;
				}

				var currentLine = startLine;
				double y = lineStartY;
				if (y + currentLine.Height > NewViewportTop) {
					for (;;) {
						lineInfos.Add(new LineInfo(currentLine, y));
						if (y <= NewViewportTop)
							break;
						currentLine = AddLineTransform(GetLineBefore(currentLine), y, VSTE.ViewRelativePosition.Bottom);
						if (currentLine == null)
							break;
						y -= currentLine.Height;
					}
					lineInfos.Reverse();
				}

				currentLine = startLine;
				for (y = lineStartY + currentLine.Height; y < newViewportBottom;) {
					currentLine = AddLineTransform(GetLineAfter(currentLine), y, VSTE.ViewRelativePosition.Top);
					if (currentLine == null)
						break;
					lineInfos.Add(new LineInfo(currentLine, y));
					y += currentLine.Height;
				}
				Debug.Assert(new HashSet<WpfHexViewLine>(lineInfos.Select(a => a.Line)).Count == lineInfos.Count);

				// At least one line must be included
				if (lineInfos.Count == 0)
					lineInfos.Add(new LineInfo(startLine, NewViewportTop));

				// Make sure that at least one line is shown
				var last = lineInfos[lineInfos.Count - 1];
				if (last.Y + last.Line.Height <= NewViewportTop)
					NewViewportTop = last.Y;
				var first = lineInfos[0];
				if (first.Y >= newViewportBottom)
					NewViewportTop = first.Y;

				return lineInfos;
			}
		void HexView_ZoomLevelChanged(object sender, VSTE.ZoomLevelChangedEventArgs e) => VisualElement.LayoutTransform = e.ZoomTransform;
		void ScrollAndMoveCaretIfNecessary(VSTE.ScrollDirection scrollDirection) {
			var origCaretContainingTextViewLinePosition = Caret.ContainingHexViewLine.BufferStart;
			bool firstDocLineWasVisible = HexView.HexViewLines.FirstVisibleLine.IsFirstDocumentLine();
			ViewScroller.ScrollViewportVerticallyByLine(scrollDirection);

			var pos = ActiveCaretBufferPosition;
			var line = Caret.ContainingHexViewLine;
			var firstVisLine = HexView.HexViewLines.FirstVisibleLine;
			var lastVisLine = HexView.HexViewLines.LastVisibleLine;
			if (scrollDirection == VSTE.ScrollDirection.Up && firstDocLineWasVisible)
				lastVisLine = HexView.GetLastFullyVisibleLine();
			if (line.VisibilityState == VSTF.VisibilityState.Unattached)
				Caret.MoveTo(line.BufferStart <= firstVisLine.BufferStart ? firstVisLine : lastVisLine);
			else if (line.VisibilityState != VSTF.VisibilityState.FullyVisible) {
				if (scrollDirection == VSTE.ScrollDirection.Up) {
					var newLine = lastVisLine;
					if (newLine.BufferStart == origCaretContainingTextViewLinePosition) {
						if (newLine.BufferStart > BufferLines.BufferStart)
							newLine = HexView.HexViewLines.GetHexViewLineContainingBufferPosition(newLine.BufferStart - 1) ?? newLine;
					}
					Caret.MoveTo(newLine);
				}
				else {
					var newLine = firstVisLine;
					if (newLine.BufferStart == origCaretContainingTextViewLinePosition && !newLine.IsLastDocumentLine())
						newLine = HexView.HexViewLines.GetHexViewLineContainingBufferPosition(newLine.BufferEnd) ?? newLine;
					Caret.MoveTo(newLine);
				}
			}
			Caret.EnsureVisible();

			var newPos = ActiveCaretBufferPosition;
			if (newPos != pos)
				Selection.Clear();
		}
			public bool IsSupported(VSTE.ITextView textView) => false;
Beispiel #17
0
		void Options_OptionChanged(object sender, VSTE.EditorOptionChangedEventArgs e) {
			if (e.OptionId == DefaultHexViewHostOptions.ZoomControlName || e.OptionId == DefaultHexViewHostOptions.HorizontalScrollBarName)
				UpdateVisibility();
			else if (!Enabled) {
				// Ignore all other options
			}
			else if (e.OptionId == DefaultWpfHexViewOptions.ZoomLevelName)
				zoomControl.UpdateTextWithZoomLevel();
		}
Beispiel #18
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>
		public void DisplayHexLineContainingBufferPosition(HexBufferPoint bufferPosition, double verticalDistance, VSTE.ViewRelativePosition relativeTo) =>
			DisplayHexLineContainingBufferPosition(bufferPosition, verticalDistance, relativeTo, null, null, DisplayHexLineOptions.None);
		void Options_OptionChanged(object sender, VSTE.EditorOptionChangedEventArgs e) {
			switch (e.OptionId) {
			case DefaultHexViewOptions.ShowColumnLinesName:
				UpdateEnabled();
				break;

			case DefaultHexViewOptions.ColumnLine0Name:
			case DefaultHexViewOptions.ColumnLine1Name:
			case DefaultHexViewOptions.ColumnGroupLine0Name:
			case DefaultHexViewOptions.ColumnGroupLine1Name:
				DelayRecreateColumnLines();
				break;
			}
		}
Beispiel #20
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>
		public void DisplayHexLineContainingBufferPosition(HexBufferPoint bufferPosition, double verticalDistance, VSTE.ViewRelativePosition relativeTo, double? viewportWidthOverride, double? viewportHeightOverride) =>
			DisplayHexLineContainingBufferPosition(bufferPosition, verticalDistance, relativeTo, viewportWidthOverride, viewportHeightOverride, DisplayHexLineOptions.None);
		/// <summary>
		/// Calculates the line transform for a given line of formatted text
		/// </summary>
		/// <param name="line">Line</param>
		/// <param name="yPosition">Y position</param>
		/// <param name="placement">Placement</param>
		/// <returns></returns>
		public abstract VSTF.LineTransform GetLineTransform(HexViewLine line, double yPosition, VSTE.ViewRelativePosition placement);
Beispiel #22
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);
		public override WpfHexView Create(HexBuffer buffer, VSTE.ITextViewRoleSet roles, HexViewCreatorOptions options) =>
			Create(buffer, roles, hexEditorOptionsFactoryService.GlobalOptions, options);
Beispiel #24
0
		void HexView_ZoomLevelChanged(object sender, VSTE.ZoomLevelChangedEventArgs e) {
			canvas.LayoutTransform = e.ZoomTransform;
			DsImage.SetZoom(canvas, e.NewZoomLevel / 100);
		}
Beispiel #25
0
			public override VSTF.LineTransform GetLineTransform(HexViewLine line, double yPosition, VSTE.ViewRelativePosition placement) =>
				owner.LineTransformProvider.GetLineTransform(line, yPosition, placement);
Beispiel #26
0
		void Options_OptionChanged(object sender, VSTE.EditorOptionChangedEventArgs e) {
			if (e.OptionId == DefaultHexViewHostOptions.GlyphMarginName)
				UpdateVisibility();
		}
Beispiel #27
0
		void EditorOptions_OptionChanged(object sender, VSTE.EditorOptionChangedEventArgs e) {
			UpdateOption(e.OptionId);
			if (e.OptionId == DefaultHexViewOptions.RefreshScreenOnChangeName) {
				if (!Options.IsRefreshScreenOnChangeEnabled())
					StopRefreshTimer();
			}
			else if (e.OptionId == DefaultHexViewOptions.EnableColorizationName)
				InvalidateFormattedLineSource(true);
			else if (e.OptionId == DefaultHexViewOptions.RemoveExtraTextLineVerticalPixelsName)
				UpdateRemoveExtraTextLineVerticalPixels();
		}
		void Options_OptionChanged(object sender, VSTE.EditorOptionChangedEventArgs e) {
			switch (e.OptionId) {
			case DefaultHexViewOptions.HighlightActiveColumnName:
				UpdateEnabled();
				break;
			}
		}
Beispiel #29
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);
		}
		/// <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);