New feature: Indicators #160
Replies: 6 comments 12 replies
-
ImplementationThe first implementation has been added to the main repo. This is the core of the implementation in SynEditMiscClasses: TSynIndicatorStyle = (sisTextDecoration, sisSquiggleMicrosoftWord,
sisSquiggleWordPerfect, sisRectangle, sisFilledRectangle,
sisRoundedRectangle, sisRoundedFilledRectangle);
TSynIndicatorSpec = record
Style: TSynIndicatorStyle;
Foreground,
Background: TD2D1ColorF;
FontStyle: TFontStyles;
end;
TSynIndicator = record
Id: TGuid;
CharStart, CharEnd : Integer;
constructor Create(aId: TGuid; aCharStart, aCharEnd: Integer);
end;
TSynIndicators = class
public
procedure RegisterSpec(Id: TGuid; Spec: TSynIndicatorSpec);
function GetSpec(Id: TGUID): TSynIndicatorSpec;
procedure Add(Line: Integer; Indicator: TSynIndicator);
procedure Clear; overload;
procedure Clear(Id: TGuid); overload;
function LineIndicators(Line: Integer): TArray<TSynIndicator>;
function IndicatorAtPos(Pos: TBufferCoord; var Indicator: TSynIndicator): Boolean;
function IndicatorAtMousePos(MousePos: TPoint; var Indicator: TSynIndicator): Boolean; SynEdit defines a public property property Indicators: TSynIndicators; UsageYou need to define and register an indicator spec, e.g.: const TestIndicatorID: TGUID = '{A5D68F5B-7E52-4649-BD69-365B68B39A52}';
IndicatorSpec: TSynIndicatorSpec =
(Style: sisTextDecoration;
Foreground: (r: 1; g:0; b: 0; a: 1);
Background: (r: 0; g:0; b: 1; a: 0.5);
FontStyle: [fsBold]);
Editor.Indicators.RegisterSpec(TestIndicatorID, IndicatorSpec); There are two options for adding/managing indicators: via a PluginThe plugin needs to handle LinePut and LinesInserted to add indicators using for instance: Editor.Indicators.Add(aIndex, TSynIndicator.Create(TestIndicatorID, charStart, charEnd); Note that SynEdit deletes indicators when their lines are deleted or edited and automatically adjusts the positions of other indicators. Also SynEdit automatically invalidates indicators on removal. via an event handlerA new event is defined that can directly provide indicators to the painting routine: type
TGetLineIndicatorsEvent = procedure(Sender: TObject; const Line: Integer;
var LineIndicators: TArray<TSynIndicator>) of Object;
property OnGetLineIndicators: TGetLineIndicatorsEvent
read FOnGetLineIndicators write FOnGetLineIndicators; Indicator stylessisTextDecorationCan change style, font color and background color of the the indicated text. The background can be solid or alpha blended: sisSquiggleMicrosoftWordsisSquiggleWordPerfectsisRectanglesisFilledRectanglesisRoundedRectanglesisRoundedFilledRectangleIndicator hints and pop up menusYou can show an indicator specific hint or an an indicator specific popup by handling the OnShowHint and/or the OnContextPopup events and test for an indicator using IndicatorAtMousePos method. Bracket highlightingYou can use indicators instead of handling the PaintTransient event to implement bracket highlighting. This is going to be a lot more efficient. I am planning to implement bracket highlighting out-of-the-box, but more on this later. DemoI will modify the spell checking component to use indicators and provide a demo. |
Beta Was this translation helpful? Give feedback.
-
Out of the box bracket highlighting is just an excellent idea. I would be happy running some tests with a provided demo |
Beta Was this translation helpful? Give feedback.
-
This looks really cool. I did some tests just using the OnGetLineIndicators event and it worked well. I hit an issue if you caret right such that the indicated string is partially shown as LeftChar progresses. A range check error and some painting and caret movement issues. Let me know if you need more steps to reproduce. |
Beta Was this translation helpful? Give feedback.
-
Hi! Thanks |
Beta Was this translation helpful? Give feedback.
-
Quick question! I may be misunderstanding the CharStart and CharEnd values. I was thinking that if I had a one character indicator, that started at position 1, that CharStart would be 1 and that CharEnd would be 1. It seems like now it has to be CharStart 1 and CharEnd 2 for it to work. Is that intended? |
Beta Was this translation helpful? Give feedback.
-
This was changed in the last commit. It is now analogous to BlockBegin, BlockEnd used for selection. So, CharEnd points to the character after the last character. |
Beta Was this translation helpful? Give feedback.
-
This is inspired by Scintilla indicators. Their most common usage is to indicate syntax errors or spelling mistakes by decorating the text. Scintilla defines 20 such indicators, the most familiar of which is the squiggly lines drawn to indicate errors. This would simplify the implementation of plugins such as the Spelling addin of SynEdit.
The suggestion is to implement this using events:
The first event will provide information about indicators to SynEdit text painting and the second event could give the opportunity to for example show a hint or popup menu or take some other action when when the user hovers the mouse on an indicator range.
These events can be implemented on the SynEdit or plugin level,
What do you think?
Beta Was this translation helpful? Give feedback.
All reactions