Updating Tag Adornment Positions when Window Contents Shift

SyntaxEditor for WPF Forum

Posted 1 year ago by Will Gauthier
Version: 22.1.4
Avatar

I'm imlementing a feature akin to delimiter highlighting, but for the scope blocks of a custom Lua syntax language, by matching with the block nodes in my abstract syntax tree. However, my highlight adornments aren't moving in tandem with the tagged text they represent. 

I've created a ScopeHighlightTagger class that inherits from TaggerBase and does offset comparisons between the snapshot ranges passed into GetTags and the AST block nodes accessible from its Document. There are also a ScopeHighlightTag that inherits ITag and a ScopeHighlightAdornmentManager that inherits DecorationAdornmentManagerBase. The adornment manager has an adornment draw callback that calls FillRectangle on the TextViewDrawContext.

It works, but the tags are only updating as their line of text is being modified. When the window scrolls or new lines are inserted above, the colored rects become misaligned with the lines of text they correspond with until you start typing in that line.

How can I get the tags to redraw their positions more dynamically, when the contents of the window shift around, instead of just when modifying the lines of text that they are tied to?

Comments (4)

Posted 1 year ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Will,

Keep in mind that the AST nodes in Document.ParseData are not generally up-to-date and are based on an older document snapshot.  This is due to parsing occurring asynchronously after text edits.  I'm not sure which parser you are using to generate the parse data, but our LL(*) Parser Framework for instance has a ILLParseData.Snapshot property where we pass the ITextSnapshot used to generate the AST data.  That way we have the capability to translate text ranges so that the AST and snapshot ranges being considered are for the same snapshot.  

My guess is that in your scenario, you are comparing new snapshot ranges from the tagger to outdated offsets from the AST.

What you probably want to do is translate the AST offsets from their source snapshot to the current snapshot before comparing them in your tagger.  That would ensure everything is looking at the same snapshot and would do a proper comparison.


Actipro Software Support

Posted 1 year ago by Will Gauthier
Avatar

Thanks for the suggestion! I am using your LL(*) Parser Framework, so I was able to translate the AST offsets to the newer snapshot before comparing them exactly as you described.

Doing so fixed the misalignment when prepending new lines above the tagged and adorned scopes but not when scrolling the window. The text and adornments seem to move at different speeds. Do you have any additional guidance?

Posted 1 year ago by Will Gauthier
Avatar

I got it working through trial and error. Initially in the DrawAdornmentCallback I was adding the adornment's Location property to the TextViewDrawContext's TextAreaBounds to generate the display Rect position. It turns out that I wanted to add the adornment's ViewLine.TextBounds instead.

I'm unclear what the adornment's Location represents/why it doesn't correspond exactly to its view line, but I'm happy to have my feature working. Thanks for the help!

Posted 1 year ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Will,

If you were only seeing the problem for horizontal scrolling, it could have been that your adornment X value wasn't accounting for the horizontal scroll state.  Check out our AdornmentsColorPreview sample's ColorPreviewAdornmentManager.OnDrawHighlightAdornment method.  There you can see how we calculate the X/Y properly when drawing the adornments.  That should give an example of best practice.

When you draw the adornment later, the drawing context is relative to the entire view, so you have to offset by the TextAreaBounds (text area relative to top/left of view), adornment location (relative to top/left of text area), and horizontal scroll amount.


Actipro Software Support

The latest build of this product (v24.1.1) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.