I need to make today's post very brief because I have been very busy today, and really want to finish my current project so I can get started on something new tomorrow.
I wish I had something really cool or interesting to say, but today I spent a very large amount of my time doing very tedious and rather annoying work. Making User Interfaces is pretty boring. Well... I should be more clear. The logic behind the UI can be a lot of fun. I have learned a lot about the complexities and everything that happens behind the scenes with User Inputs and such, but the actual scene is realllyyy annoying to make.
I spent hours today just trying to get a cursor (or as a later learned, it is actually called the caret) to pixel perfect fit the text across different types of input panels. The problem is that the text lines up in drastically different ways in, for example, a text box vs. a text area. Text boxes always have the text centered, and thus the caret must also be centered. In a text area, the text will start at the very top, and will of course span across several lines, thus the caret must operate in a fundamentally different way than in a text box.
Now if you are just trying to get everything to work, you can hack in easy ways to make the caret look right, without it actually being able to truly work right. For example you could easily code in an exact length for the caret, and exact positions for it to start on every line, but then you could never change the size of the font or the area itself. You could also design drastically different carets for a text box and a text area, but the problem is that there is just enough similarities between how they have to be made that you would end up with a lot of duplicate code.
In the end I found ways to get pixel perfect carets for the different input panels, using mostly all the same code with very little duplication, but it took large amounts of experimentation and fiddling with different offsets and such.
What made it worse was, and I hate to say this, trying to accomplish this with TDD. It was a mistake. Any change I had to make to the size of the caret, or the position/coordinates I wanted it to be at, or the manner in which it was positioned... I had to make these changes in every test as well as in the production code. This is wrong, and is not how coding should be done. I am inclined to say that when designing UIs, it is better to just put some tests in after you know you have everything looking the way you want. I mean... tests just can't tell you how something will look. You can write a test that seems to make sense in how the positioning will work, but then you run the program and everything is completely misaligned or the cursor is actually 2 pixels too long at the top and 3 pixels to short on the bottom. There are just too many nit picky little things involved in the presentation of UIs that TDD can't help you with.
Please, if you disagree or know a better way, tell me.
Paul suggested I read the Humble Dialog Box by Michael Feathers, which is an excellent article on how to separate your UI from all your logic. I will blog further about this today.