Set background color for a word in textarea?

Hello

Is it possible to set a background color for a specific text/word in a textarea (not HTML) Desktop App? I’ve seen there are some textstyle options but couldn’t find background color for text. I have the code to evaluate the word I want to set a background color. So I’m only asking if that is somehow possible.

If not then sad but ok. Just want to know/make sure there is no (in)official option.

Xojo’s TextArea doesn’t support this RTF property. Formatted Text Control is able to do this.

using strictly a TextArea and StyledText… the answer is no…

I’ve seen it done by setting the TextArea background to transparent, and using an underlying canva to draw the highlight

Ok, thank you all! Will play around with the Canvas option, nice idea!

I can imagine this will not work on Windows with the pseudo transparency Xojo is using there. IMHO a Canvas that will do the text output too would be the only solution – basically what FTC does.

While Xojo does not support it, we have methods for this in MBS Plugins for Mac and may be able to add for Windows, too.

If you have a line of text and just want to background a single word or group of words in that line of text, this is an approach. If there are going to be multiple lines or multiple words highlighted than this code will have to become more complicated. Anyway, I submit the below just as a starting point. I recently wrote this code prompted by Tim Parnell’s insistence that it was doable and more robust than a solution I had cobbled together using an HTML area and an overlying tranparent canvas. I needed the ability to detect a Mouse Click on the text, and HTML areas do not own this event.

This was my approach. You might find something useful here.

Create a class (HighlightText) that is a subclass of a canvas.
Give it three properties:
lengthHighlight (int) Contains the length of the highlighted segment
startHighlight (int) Contains the index of the first letter of the highlighted segment
theString (string) Contains the entire line of text.

Below is the code for the Paint event of the canvas. Basically, think of the line of text as having three segments: 1. Before the highlighted area; 2. Area that is highlighted; 3. After the highlighted area: (str1, str2, str3). You are going to draw the text one after another and the text in the middle is going to be highlighted by having a colored rectangle painted behind it.

In the example below, the highlighted text is also slightly larger than the rest of the text which is why there is a different size for the text in the middle (highlighted) segment. str2. This just related to my use case.

Basically, you have to figure out where and how large to draw a rectangle in your canvas that is going to be behind the segment of text that is to be highlighted. One detail is that the rectangle is going to have to extend down a little to be able to cover the descenders of the text segment.

And then in the Paint Event of the canvas:

[code]Var theString As String = Me.theString
Var theStart As Integer = Me.startHighlight
Var theLength As Integer = Me.lenghHighlight

Var lengthEntire As Integer = theString.Length
// to do anything, these values have to be consistent and describe something to highlight
If lengthEntire < theStart + theLength Then Return
If theStart <= 0 Then Return
If theLength <= 0 Then Return

Const FONT_DISPLAY As String = “Andale Mono”
Const FONT_SIZE_BEGIN_END As Integer = 18
Const FONT_SIZE_MIDDLE As Integer = 20
Const PAD As Integer = 2
Var COLOR_BACKGROUND As Color = RGB(256, 215, 0) // Gold
// descenders are roughly 1/4 the height of the string
Const DESCENDER_FRACTION As Double = .25
// where the left edge of the text is in the Canvas
Const START_TEXT_X As Integer = 10
// where the bottom of text is to be placed in the Canvas ignoring descenders
Const START_TEXT_Y As Integer = 30

Var str1 As String // before highlight
Var str2 As String // to be highlighted
Var str3 As String // after highlight

Var widthstr1, widthstr2, widthstr3 As Double
// TextHeight is calculated as the maximum height for the font itself and not the actual height of the text. Actual text irrelevant
// For example, with “a” vs. “A”, both return the same TextHeight even though “A” has a greater height than “a”.
Var heightstr1_3, heightstr2 As Double
Var descenderProblem2 As Double
str1 = theString.Left(theStart)
str2 = theString.Middle(theStart, theLength)
str3 = theString.Right(lengthEntire - (theStart + theLength))

// figure out the height and width of the parts of the string
g.TextFont = FONT_DISPLAY
g.TextSize = FONT_SIZE_BEGIN_END
widthstr1 = g.TextWidth(str1)
heightstr1_3 = g.TextHeight()
widthstr3 = g.TextWidth(str3)
g.TextSize = FONT_SIZE_MIDDLE
widthstr2 = g.TextWidth(str2)
heightstr2 = g.TextHeight()
descenderProblem2 = heightstr2 * DESCENDER_FRACTION

// draw the text before the highlight
g.TextSize = FONT_SIZE_BEGIN_END
g.DrawingColor = Color.Black
g.DrawString(str1, START_TEXT_X, START_TEXT_Y)

// highlight background rectangle
Var startRectX As Integer
Var widthRectX As Integer
g.DrawingColor = COLOR_BACKGROUND
startRectX = START_TEXT_X + widthstr1 + PAD
widthRectX = widthstr2
g.FillRectangle(startRectX, START_TEXT_Y - heightstr2 + descenderProblem2, widthstr2, heightstr2) // upper left X, upper left Y, width, height

// draw the highlighted text
g.DrawingColor = Color.Black
g.TextSize = FONT_SIZE_MIDDLE
g.DrawString(str2, (START_TEXT_X + widthstr1 + PAD), START_TEXT_Y)

// draw the text after the highlight
g.TextSize = FONT_SIZE_BEGIN_END
g.DrawingColor = Color.Black
g.DrawString(str3, (START_TEXT_X + widthstr1 + PAD + widthstr2 + PAD), START_TEXT_Y)[/code]

If you don’t need to edit the text, it is easy to create outlines with CSS in an HTML page, shown in HTMLViewer.

We’ll add new properties via MBS Xojo Win Plugin:

WinSelTextBackColorMBS as Color WinSelHasTextBackColorMBS as Boolean

to cover the Windows side. And I’ll think I will have an example to do it for Mac & Windows.

Thanks all for the information! I’m currently working on a code tool where users enters code into a textarea. Everything is working fine like uppercasing of keywords, coloring keywords, etc. It would be nice if a user could doubleclick on a single word (usually code word). I then would highlight (set backgroundcolor) where else it’s found inside the textarea. That way the user can easily see where else this (code)word is used. Doubleclick on a highlighted word would un-highlight all others as well. Of course I can also work with f.e. “bold” but color highlighting of text is the usual way in coding tools. Furthermore I need a solution working on Win, Mac and Linux (Desktop).
I’m aware HTML (viewer) can do that out of the box but the user needs of course to change his code. :wink:
Canvas: Tbh I haven’t looked into it in detail. Not sure how good/easy it supports my already implemented features. Furthermore I already can recognise the word behind the mouse cursor. I also plan that user can change font and fontsize. Not sure how easy that all in Canvas is. A TextArea can also expand automatically. I assume I have to take care of Canvas height on entering text.

That sounds complicated enough that I would forego background color highlighting and use Styled Text in a Text Area with colored and bold text to indicate what needs to be highlighted. Trying to do what you want to do with a Canvas would seem to me to be really complicated.

@Robert Livingston Thank you for your additional input which confirms my assumptions.