As most of my family and friends already know, I had a fairly serious heart attack in late November of 2020 while working in Idaho. It required a quintuple bypass surgery to keep me in the world a little longer. It’ll still be a few more weeks before I can legally re-certify (I’m a truck driver) and get back to work. So I’ve been sitting here at home in Mississippi trying to keep myself occupied and entertained.
But how to stay occupied for weeks and weeks at home when I’m accustomed to running hard and seeing the country? Fortunately I love to read and have a sizable library of books I’ve bought over the years (I don’t throw away books). And I have a ton of movies and TV shows on disk and on iTunes (I don’t have cable).
But I also have a weird (for a truck driver) hobby. I love to write computer code. I personally don’t see this as weird, but given the amount of flack I’ve caught over the years, it’s fair to assume that most of my brethren find it an odd choice for a trucker’s hobby. Most of that flack has just been good-natured fun, but not all. I’ve even been accused of being gay just because I know how to type. I figure those making such accusations are the same ones that buy massive 4×4 pickup trucks to compensate for having a tiny penis.
Going off-topic just briefly…
If you think it’s an insult to accuse someone of being gay, that says a lot more about you than it does the person you’re accusing. By the same token, if being accused of being gay is insulting to you, same thing. You’re likely a homophobe and a coward, and frankly unworthy of membership in the human race. To answer your obvious question, no I’m not. But if I were I certainly wouldn’t try to keep it a secret. You can like me or not like me. I truly don’t care, and why would I?
And for the record I am not an especially proficient typist. I’m more of a 2-fingered pecker. But anyway…
OK, back on topic…
Anyway, I had a couple of projects I’d been tinkering on for over a year but hadn’t had time to finish them. Once I got home from the hospital in Idaho I had nothing but time, so I’ve been hitting them nearly every day. One was a plain text / HTML editor (above). I occasionally need to write a bit of HTML and I have never found an editor on the market that suited me. So I rolled my own. It is if I may say so (and I do), just a damn nice HTML editor. However, it didn’t 100% suit me for writing the occasional blog post. Code editors and word processors are very different even though they both deal with text. And I didn’t want to keep using Libre Office for my blog. Libre Office’s “Writer” is a wonderful word processor but it’s better suited for big jobs, not a post to my tiny blog.
So, I decided to roll my own app for writing blog posts (above). I do my desktop programming with Microsoft’s “Visual Studio Community Edition” (Visual Basic language) application. It’s wildly popular for a reason – it’s powerful and effective. It’s also free, unlike the Enterprise version of Visual Studio which is damnably expensive. But there is a drawback in this case. The “Rich Text Box” VS provides has very limited capabilities. I needed something better. After a bit of digging online, I found the “TXTextControl.” Much to my relief it has a limited license to use the product for free (personal or non-commercial use only). It’s an amazing tool capable of doing anything a full-grown word processor can do. The free version has limits, but nothing I can’t live with especially since the commercial version of the control costs over a thousand dollars for a minimal license. This is not a knock against the company or their product. For a commercial developer it’s a reasonable price for what you’re getting. But since I don’t do this for money, I like free stuff.
Of course I also needed a spell-checker. In this case I didn’t have to hunt because I was already using “NHunspell” in my aforementioned HTML editor. However, getting it to work with the TextControl turned out to be a challenge. NHunspell works by comparing a word you send it to its dictionary. If the word isn’t in the dictionary it’ll provide a list of suggestions. With plain text and HTML code this is easily done. One uses Regular Expressions to isolate each individual word in a document and send it to NHunspell. But without getting too deeply into the details, it was different with TXTextControl because of how a word processor handles individual lines and non-printed characters in the line endings.
With plain text or HTML code, a line is a line, regardless of whether it’s wrapped or not. But with a word processor each visual line constitutes a physical line. For example in the paragraph above, in a plain text or code editor it’s one physical line that just happens to be wrapped several times to fit in the allotted space. But with a word processor each time it wraps constitutes a new physical line. It may not sound like a huge thing but it took me hours to finally figure out how to make it work.
NHunspell does the background work, but I still had to create the user interface and write the code to find each word and tell all the buttons what to do with themselves. Again, there were slight differences to figure out between a plain text editor and a word processor. Visual Studio’s debugging tools are helpful with this so that part didn’t take all that long.
Next came the creation of a Find / Replace tool. TXTextControl has one built-in but I didn’t especially like it. So once again I had to roll my own. This was easy since TXTextControl provides several commands for finding and replacing text without the built-in dialog box. Combining the built-in tools with Regular Expressions gave me a sweet Find-Replace tool.
But what, some of you may be wondering, the Hell are Regular Expressions? Well first, “Regular Expressions” (aka RegEx) is singular, like “politics.” It’s a highly specialized language for searching and replacing text. It uses patterns instead of literal searches sort of like the wildcard characters some programs use in searches. It’s way too involved to give you a decent explanation here, but here’s an example of what I mean by patterns:
The RegEx pattern above will find any US phone number in a document providing that the area code, prefix and last four are delimited by a single space, like: 555 666 7777, and that the 3rd digit in the prefix is a 3 and the 3rd digit in the last four is a 9. The “\d” RegEx symbol means “any digit.” The “\s” symbol represents a single white space character. There’s a lot more to RegEx but I won’t bore you with it here. Frankly, I’m surprised you’re still here reading this. I’m only writing it to try out my new word processor I’m gabbing about.
As to the user interface, the TextControl comes with a “ButtonBar” for text alignment, bold, italic, etc. Surprisingly, it doesn’t include buttons for text and background colors, and none of the buttons have ToolTips. I added two buttons right of the TXTextControl’s ButtonBar to handle changing the colors of the text and background color of a text selection. It’s too long to display it as is so I divided the tool bar into three sections. First my own buttons, then the ButtonBar and lastly the two buttons to change colors.
The tool bar buttons left of the ButtonBar are also just plain old Windows buttons. Everything is then dropped in a control called a TableLayoutPanel which lets me treat the whole thing as a group. Took just a little work to get the ButtonBar and the other buttons to look like they belonged together. Fortunately both TXTextControl and Visual Studio have some basic options for control styles.
But there was an issue here. The TXTextControl ButtonBar does not support tooltips for its buttons (Tooltips are of course the little message balloons that pop up when your mouse hovers over a button). All my other tool bar buttons have tooltips, and tooltips for tool bar buttons is a sort of convention. Maybe even a tradition. So by dammit Martha, we gonna figure out tooltips for the ButtonBar.
It turns out that since the ButtonBar itself is a Windows control, it supports having a tooltip by default. But it’s for the entire control and not the individual buttons. And, like most any Windows control it also supports responding to mouse events (Move, Hover, Leave, Enter etc) and this provided the opportunity I needed.
First I wrote a brief bit of code to respond to the ButtonBar’s MouseMove event. I added a ToolTip to the form (a “form” is the application’s window in this case). Setting / changing the ToolTip property for a control is easy. And, like most tool bars, the ButtonBar’s buttons highlight (change color) when the mouse hovers over them. Using this, I had my code set the ButtonBar’s tooltip to the mouse’s XY coordinates as the mouse moved across the control. I simply made a note of the left X coordinate when the mouse entered a button’s rectangular area and of the right X coordinate when the mouse left it. Since the buttons are horizontally aligned and all the same size, the Y coordinates are all the same.
I was thusly able to create an array of rectangles of all the buttons (above). I created another array containing the intended ToolTip values for each button (above). From these I created a Key / Value Dictionary (just above) in which the tooltips’ text values were the keys and the rectangles were the values.
From there it was just a matter of again handling the ButtonBar’s MouseMove event (above). As the mouse moves across the control, a new 1×1 pixel rectangle is created from the coordinates of the mouse. If the mouse rectangle intersects with a button’s rectangle, the appropriate tooltip is assigned to the ToolTip component I added to the form. Easy Peasy, right?
TXTextControl also comes with a RulerBar but I haven’t really messed with it yet. I dropped it into the form but that’s just because the program looked incomplete without it. Maybe tomorrow.
Debugging wasn’t a huge undertaking once I had the RegEx for the spell checker figured out. Most of the problems I encountered were just goofs I made in my own code (yeah, I have those a lot) and so they weren’t that hard to fix.
All in all this wasn’t the biggest or hardest coding project I ever tackled. It was a lot easier than the aforementioned HTML editor since this one just works with a single file while the HTML editor is a tabbed, multi-document environment with lexers for several programming languages. And no hobby project is ever truly “finished.” Weirdos like me always think up something new, or we see something someone else has done and want to try it ourselves. I’ve published a few projects at the CodeProject website, though none lately.
As with most hobbies, it isn’t so much the use of the project once it’s done. The satisfaction comes from the building. I have family who are heavily into model train layouts. It’s the same for them. The satisfaction and the joy come from the creative process more than the finished product.
Are you still here? Aren’t you bored yet? Well thanks for sticking with me. I hope you enjoyed the read. And don’t worry. Next time I’ll get back to bashing on someone I disagree with. Wouldn’t want anyone to think I was going soft in my old age. 😀
Until next time, ਆਸਮਾਨ ਸਾਫ.