Adornments which cannot be selected

SyntaxEditor for WPF Forum

Posted 8 years ago by Rick Fleuren
Version: 11.1.0545
Avatar
We use a SyntaxEditor with inline buttons (popupbutton) that represent markers inside the text of the editor. Those markers get stored at their exact location in our databases.

Example:

Some text, [marker] and some other text.

Is stored as:

Some text, and some other text
Marker position: 11

Now we've solved these little markers/buttons with the AdornmentManager. We place those buttons as you guys did in the Code Review example, but without a range. However we stumble upon some problems. These markers are part of the text they are in, and when we only wish to select one of these markers, we cannot do this, because the items in the adornment layer are not part of the underlying text.

It also becomes most difficult to select one of these markers when we only have one marker in the editor with no further accompanying text. We understand that the range of one of these adornments is set to 0, and therefor the editor cannot select a range of 0 characters. But how can we overcome this difficulty?

Are adornments the way to go in this situation? If so, how can we solve this problem, or would you recommend using something different than adornments?

[Modified at 11/01/2011 10:21 AM]

Comments (10)

Posted 8 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Rick,

Correct, intra-text adornments don't take up any offsets and thus can't be selected. The only thing I can think of is to have you do something like what we do in the CollapsedRegionsAdvanced QuickStart.

There we collapse one or more characters and replace it with an adornment. This would require you to inject some marker character of some sort in your text so that it takes up an offset. But other than that, I would think it would behave how you want since then you could select it, etc.


Actipro Software Support

Posted 8 years ago by Rick Fleuren
Avatar
I am now implementing the suggested solution with the ICollapsedRegionTag which seem to work by inserting a marker character, so that we can select the tag in question.

We still use IIntraTextSpacerTag to denote ranges that have conditions and such.

All things seems to work nicely side by side, but as soon as I declare a ICollapsedRegionTag inside an IIntraTextSpacerTag's range, I get the following exception:

An item with the same key has already been added. -> See InnerException for details
  ----> System.ArgumentException : An item with the same key has already been added.

--ArgumentException
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at ActiproSoftware.Windows.Controls.SyntaxEditor.TextFormatting.TextViewLineLayout..ctor(Int32 A_0, Int32 A_1, Int32 A_2, Boolean A_3, Double A_4, TextLine A_5, a0 A_6, IList`1 A_7)
at as..ctor(Double A_0, Double A_1, TextRange A_2, IList`1 A_3, a0 A_4, IList`1 A_5)
at e.a(ITextView A_0, ITagAggregator`1 A_1, ITagAggregator`1 A_2, TextRange A_3)
at h.a(ITextView A_0, ITagAggregator`1 A_1, ITagAggregator`1 A_2, TextRange A_3)
at h.a(ITextView A_0, ITagAggregator`1 A_1, ITagAggregator`1 A_2, Int32 A_3, Double A_4, Double A_5)
at ActiproSoftware.Windows.Controls.SyntaxEditor.TextFormatting.TextViewLineLayoutManager.a(ITextView A_0, ITagAggregator`1 A_1, ITagAggregator`1 A_2, Size A_3, TextPosition A_4, Boolean A_5)
at ActiproSoftware.Windows.Controls.SyntaxEditor.Primitives.EditorView.i()
at ActiproSoftware.Windows.Controls.SyntaxEditor.Primitives.EditorView.GetViewLine(Int32 offset)
at ActiproSoftware.Windows.Controls.SyntaxEditor.Primitives.EditorView.GetViewLine(TextPosition position)
at ActiproSoftware.Windows.Controls.SyntaxEditor.Primitives.EditorView.GetCharacterBounds(TextPosition position)
at ActiproSoftware.Windows.Controls.SyntaxEditor.Implementation.EditorViewSelection.c()
at ActiproSoftware.Windows.Controls.SyntaxEditor.Implementation.EditorViewSelection.a(TextRange A_0, SelectionModes A_1, Boolean A_2)
at ActiproSoftware.Windows.Controls.SyntaxEditor.Implementation.EditorViewSelection.SelectRange(TextRange newTextRange, SelectionModes newMode)
at ActiproSoftware.Windows.Controls.SyntaxEditor.Primitives.EditorView.OnCollapsedRegionManagerRegionsChanged(Object A_0, TextSnapshotRangeEventArgs A_1)
at ActiproSoftware.Windows.Controls.SyntaxEditor.Implementation.CollapsedRegionManager.a(TextSnapshotRangeEventArgs A_0)
at ActiproSoftware.Windows.Controls.SyntaxEditor.Implementation.CollapsedRegionManager.a(TextSnapshotRange A_0)
at ActiproSoftware.Windows.Controls.SyntaxEditor.Implementation.CollapsedRegionManager.a(Object A_0, TagsChangedEventArgs A_1)
at ActiproSoftware.Text.Tagging.TagAggregatorBase`1.OnTagsChanged(TagsChangedEventArgs e)
at ah.a(TagsChangedEventArgs A_0)
at ah.d.a(Object A_0)
at x.a(DependencyObject A_0, Action`1 A_1, a A_2)
at ah.OnTagsChanged(TagsChangedEventArgs e)
at ActiproSoftware.Text.Tagging.TagAggregatorBase`1.a(Object A_0, TagsChangedEventArgs A_1)
at System.EventHandler`1.Invoke(Object sender, TEventArgs e)
at ActiproSoftware.Text.Tagging.Implementation.TaggerBase`1.OnTagsChanged(TagsChangedEventArgs e)
at ActiproSoftware.Text.Tagging.Implementation.CollectionTagger`1.a(ITextVersionRange A_0)
at ActiproSoftware.Text.Tagging.Implementation.CollectionTagger`1.Add(TagVersionRange`1 item)
Can you point me out on how to resolve this issue, because I have no idea which key he is complaining about ;).

Thanks in advance,

Rick
Posted 8 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Rick,

I'd recommend that you use a single tag for both ICollapsedRegionTag and IIntraTextSpacerTag. For instance in the CollapsedRegionsAdvanced QuickStart, we define our tag as:
public class CollapsedRegionTag : ICollapsedRegionTag, IIntraTextSpacerTag { ... }
That should fix this.


Actipro Software Support

Posted 8 years ago by Rick Fleuren
Avatar
True, I won't get an exception anymore, but:

when I use the same object tag for both ICollapsedRegionTags and IIntraTextSpacerTag , the ICollapsedRegionTags now act as IIntraTextSpacerTag (and won't replace my marker character), and the IIntraTextSpacerTag now hides all the text that it needs to highlight.

Extra information: I've used one tagger with the one tag, and I have two adornmentmanagers, but I don't think that matters much (does it?).

How can I find a solution, perhaps with one tag both interfaces implemented, while preserving that each tag acts like it should:
  • The IIntraTextSpacerTag highlights a region, which can also consist of IIntraTextSpacerTags and ICollapsedRegionTags
  • The ICollapsedRegionTags collapse my marker character so that it can be selected, and won't throw exceptions when inside the IIntraTextSpacerTag
Thanks for your help,

Rick
Posted 8 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Rick,

What you originally described was that you wanted to inject a marker into the text flow. So by using a single tag that is both ICollapsedRegionTag and IIntraTextSpacerTag, you should be able to achieve that if you "wrap" a dummy character with the tag. The collapsed region portion of it will hide the dummy character, while allowing the range to be selected. The intra-text spacer portion (when also paired with an adornment manager) should allow you to reserve space for the marker glyph and then render it via the adornment manager. The logic there is pretty much identical to the CollapsedRegionsAdvanced QuickStart.

If there are additional requirements, maybe you could email us directly with some screenshots and more info so we can better understand what you're trying to do. But per above, I would think that it would work fine for what was originally described.


Actipro Software Support

Posted 8 years ago by Rick Fleuren
Avatar
Email sent to support@!
Posted 8 years ago by Rick Fleuren
Avatar
We have now installed the new 2011.2 with the restyled themes, so I can finally work on this issue some more.

Another problem now arises when both the IClassificationTag tag and the ICollapsedRegionTag are at the same position. One of the tags just disappears.

This is pretty odd, because several IClassificationTag tags can be next to eachother without any problem. Also several ICollapsedRegionTag at the same position is no problem. But as soon as a IClassificationTag and ICollapsedRegionTag are put next to eachother, one of them disappears.

When one tag is removed, the other tag suddenly appears again.

How can we solve this issue?

PS: I've send the updated example code to support, so that you can reproduce this issue.
To reproduce: Select some text, click on add range. Now set the caret right behind the IClassificationTag with the R, and click add field. Now see the IClassificationTag with the R disappear and see the ICollapsedRegionTag with the F appear! Now remove the field with the red button, and see the F appear again.

[Modified at 02/09/2012 07:26 AM]
Posted 8 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Rick,

I think the problem here is that you have your "range" set to expand on first edge. So say you have a range inserted, then you insert a field (which you use a section character and collapse it) at the range's start offset. Since your expand first edge option is set on the range, it grows to include the field's offset as well. Then the line renderer sees that the start character of the range is collapsed so it doesn't render its adornment.

If you change your ranges to use TextRangeTrackingModes.ExpandLastEdge instead of TextRangeTrackingModes.ExpandFirstEdge, I believe it will work better for you.


Actipro Software Support

Posted 8 years ago by Rick Fleuren
Avatar
Hey Bill,

That seems to work, but we want the field to be part of the range.

Also, users are able to create a field, select that single char field add a range around is. If we do a range with a single field, the field still disappears. I've tried it with ExpandLastEdge, ExpandFirstEdge and with no expands at all, but the field still disappears.

Any suggestions on how to make this work?

Best regards,

Rick
Posted 8 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Rick,

I've spent a while on this today but am not sure the best way to approach it. There was a bug where in your first case you selected a word and inserted a range. Then at the start of the range, you inserted a field. In that case both adornments should show but didn't. That is now fixed for the next maintenance release.

The other issue as you mentioned is when you have a collapsed region and two intra-text adornment regions for the same range. In that case the first one encountered is used to "replace" the collapsed text and render it (similar to what a "..." does for outlining nodes). The second one is then considered contained by the collapsed code and is hidden.

Even if that logic were changed, I'm not sure we can show both because collapsed ranges should only have one offset to either side of them and this would effectively create three offsets around the collapsed range which would mess up selection, etc.


Actipro Software Support

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.