I have a text area that’s used to show a scrolling log of stuff my app is doing. most of what’s there is just informational but occasionally there’s something important. Is there an easy way to style a line of text being written to a scrolling DesktopTextArea as i’m writing to it using AddText? The stuff I’m writing there can be pretty rapid-fire and when it’s in verbose mode there’s a lot of text being written. So I want to avoid having to search for anything and then style it.
This is not that big a deal, but it would be a nice addition if I can do it.
My code so far for this logging method looks like this (haven’t implemented the tests to determine severity yet):
//Severity = 0: Informational (this is the default)
// 1: Warning (Bold)
// 2: Error (Red and Bold)
// 3: Critical Error (we log this to the system log as well)
var logEntry as string = message
MainWindow.taLOG.AddText(logEntry + EndOfLine)
Before you add the new text, get the current text length. Then add the new text, set the selection start to that value and the selection length to the length of the text you’re adding. Then you can set the SelectionTextColor to what you want.
Cool. I’ll give this a try this morning. How reliable is something like this when there are multiple functions that could be writing to that text area, including messages coming from threads? I can imagine a situation where two lines are added basically simultaneously and part of the wrong line gets bolded and colored red because another message snuck in there before that could happen. or is that really unlikely?
ok so i have this implemented now, but one thing that’s a little annoying is that the last line of text shows as selected. Is the best way to “unselect” this to just set the SelectionStart to the size of the textarea? That’s what I’m doing now. I didn’t see anything in DesktopTextArea for unselecting a selection.
var talength as integer = MainWindow.taLog.Text.Length
var msglength as integer = message.Length
MainWindow.taLOG.AddText(message + EndOfLine)
//Select the area we'll style, if we're styling it
MainWindow.taLog.SelectionStart = talength
MainWindow.taLog.SelectionLength = msglength
But this simplified version does not:
MainWindow.taLOG.AddText(message + EndOfLine)
//Select the area we'll style, if we're styling it
MainWindow.taLog.SelectionStart = MainWindow.taLog.Text.Length
MainWindow.taLog.SelectionLength = message.Length
The only difference here is that I’ve eliminated the talength and msglength variables, and instead I’m getting the numbers I need where I specify SelectionStart and SelectionLength
That feels like a bug. When I run my app, both SelectionStart and SelectionLength are correct in the first case. In the second case, SelectionStart is correct but SelectionLength is zero.
String.Length is supposed to return an integer, so shouldn’t I be able to call it directly like this rather than passing it through an explicitly cast Integer first?
Ahh. nevermind. I see what’s happening here. It’s calculating the start position after the text was inserted, so effectively selecting nothing, since that SelectionStart comes after the end of the text.
However, I don’t really get why the message.length, which should be an integer, is coming up as zero in the text area’s SelectionLength property when I use it directly in this line:
MainWindow.taLog.SelectionLength = message.Length
But is correct if I first stuff it into an integer and then call that:
var msglength as integer = message.Length
MainWindow.taLog.SelectionLength = msglength
is that because you can’t have a length that extends beyond the length of the textarea so Xojo is setting that value to 0?
If you attempt to add text (or otherwise alter a text area) from a thread, you’ll get a ThreadAccessingUI exception; you can’t do that.
Whatever way you choose to add text, it’ll always be from the main thread, so always one add at a time. So, no, this can’t happen.
Almost. It’s the OS which does that. Try for yourself: in a text area, put this text: “abcde” and this code in a push button:
TextArea1.SelectionStart=4
TextArea1.SelectionLength=1000
Of course, the text area can’t hold 1000 selected characters; SelectionLength isn’t just a property, it’s like a computed property (the control fixes erroneous values).
If later you check:
MessageBox TextArea1.SelectionLength, you’ll have the actual length (fortunately).