Indicators are text decorators that can accept mouse clicks and mouse releases, similar to hotspots, but they have many more styling and property options. In fact, the creator of (Q)Scintilla himself encourages the use of indicators instead of hotspots. We’ll find out why very soon.
Defining a hotspot (memory refresh)Before we’ll consider how an indicator is created, let’s first look back at how hotspots were created. Remember the following figure:
Our lexer holds three styles: myStyle_0, myStyle_1 and myStyle_2. These are all QsciStyle-objects with their own properties. As you’ve learned in the Syntax highlighting chapter, you can use the
setStyling(function to apply a certain style on some text in the editor. nr_of_chars, style_nr)
Now imagine you want myStyle_1 to be a hotspot style. Well, you know from the hotspots chapter how to turn a normal-style into a hotspot-style. All text belonging to that style automatically turns into hotspots.
Defining an indicator
It’s time to introduce indicators. As you can see on the figure below, they are conceptually totally different from hotspots.
To define an indicator, use the following function:
self. __editor.indicatorDefine( indicator_type, indicator_number)
Architectural difference hotspot vs indicator
First of all – unlike hotspot-styles – indicators are not part of the Lexer. In fact, the editor himself – not the Lexer – keeps a list of all the defined indicators. Each indicator is (probably) a QsciIndicator-object. This object has many attributes, like:
- foreground color
- hover foreground color
- hover type/style
I would need to dive into the underlying C++ code to be sure about the term QsciIndicator-object, but the given model in the figure above is okay for all practical purposes.
By the way, no more 32 QsciIndicator-objects can exist for one editor.
Relationship to QsciStyle-objects hotspot vs indicator
As you can clearly see on the figure, indicators are in no way tied to QsciStyle-objects. They operate totally independent. And that’s important. Imagine the following example:
Just like “hotspot”, the term “indicator” leaves room for two interpretations. The following definition attempts to clarify:
The term indicator is ambiguous. It can refer to an
The term can also refer to a piece of
Applying an indicator-style on text old-fashioned way
Applying a hotspot-style on text was easy. You just define a certain style (QsciStyle-object) to be a hotspot, and all text belonging to that style automatically turns into hotspots.
Since indicators operate independently from existing styles,
# Tell the editor which indicator-style to use # (pass it the indicator-style ID number) self. __editor.SendScintilla(QsciScintilla. SCI_SETINDICATORCURRENT, indicator_number) # Assign a value to the text self. __editor.SendScintilla(QsciScintilla. SCI_SETINDICATORVALUE, value) # Now apply the indicator-style on the chosen text self. __editor.SendScintilla(QsciScintilla. SCI_INDICATORFILLRANGE, start_pos, nr_of_chars)
The first function simply tells the editor which indicator-style you want to use. Think of it as a command to pick up a certain text marker. The second function assigns a value to the text you’re going to indicate. This will be useful when the user clicks the indicated text (more on that later). The third function actually indicates the text. The parameter
Honestly, counting characters from the very beginning of your editor’s text is quite … clumsy. Luckily, QScintilla provides a way to get that start position easily:
self. __editor.positionFromLineIndex( line, col)
As first parameter
To clear the indicator, use the following functions:
# Tell the editor which indicator-style to clear # (pass it the indicator-style ID number) self. __editor.SendScintilla(QsciScintilla. SCI_SETINDICATORCURRENT, indicator_number) # Now clear the indicator-style from the chosen text self. __editor.SendScintilla(QsciScintilla. SCI_INDICATORCLEARRANGE, start_pos, nr_of_chars)
Applying an indicator-style on text new way
The previous paragraph showed how to apply an indicator using three consecutive
self. __editor.fillIndicatorRange( line_from, col_from, line_to, col_to, indicator_nr)
The function to clear the indicator is very similar:
self. __editor.clearIndicatorRange( line_from, col_from, line_to, col_to, indicator_nr)
But there is a serious downside to using these newer (and simpler) functions. When applying an indicator, you can store a value that can be retrieved when the indicator-text is clicked. Unfortunately, you have to use the old-fashioned
Indicator look and feel
You can define several properties that impact the way your indicators look.
Type / Style
When defining a new indicator, you have to determine its type:
We already covered that in the paragraph Defining an indicator. There is no need to repeat the whole table here.
Hover Type / Style
You can change the style when a mouse cursor is over the indicated text:
self. __editor.setIndicatorHoverStyle( indicator_type, indicator_nr)
This function selects the indicator’s foreground color, which is the color that is displayed when
there is no mouse cursor over the indicator.
self. __editor.setIndicatorForegroundColor( indicator_color, indicator_nr)
Hover foreground color
This function selects the indicator’s hover foreground color, which is the color that is displayed when
there is a mouse cursor over the indicator.
self. __editor.setIndicatorHoverForegroundColor( indicator_color, indicator_nr)
Draw under style
This function selects whether the indicator is painted under or above the text:
self. __editor.setIndicatorDrawUnder( draw_under, indicator_nr)
We didn’t cover yet the most important: making text ‘clickable’ with indicators. Thats something for the next page..