Monday, March 25, 2013

Gridiron Solitaire #48: The Rabbit Hole

I've been struggling with font sizing for the main and sub-headlines for months now.

The central problem is that while many things in a WPF application scale automatically, text isn't in that category--at least, not when the window loads. If the text fits after the window loads, then it will scale properly if the user resizes the window.

So it's a multi-stage problem. One, size the font properly for headline text (which is dynamic), then be sure it's still sized properly at a variety of user resolutions.

I'd been hacking through this for quite a while by hard-coding font size based on string length. So if the headline has 17 characters, the font size is X, and if it's 19 characters, it's X-2. Or something.

That hack creates its own problem, though, because different letters are different widths (unless I used a fixed font, which doesn't look good at all). So a 17-character headline, depending on the content, has a variety of possible widths.

At some point, I had to figure out a way to fix this. Headlines can't be clipped, no matter the situation. It's a good example of how clunky WPF can be (even though it's entirely brilliant in many other ways).

So I was thinking about this last week and I realized that there was (seemingly) a simple solution: why not measure the actual width of the text, based on font size, and if it doesn't fit into the actual width of the hard-coded headline label, reduce the font by 1 point and measure again. Keep measuring until it fits.

Geez, I should have realized that a couple of years ago.

Conceptually, that's a simple solution. And obviously, there should be a simple tool to measure the string, right? Well, not quite. There's an easy tool for a WinForms application (it's called "MeasureString"--imagine that), but it doesn't work in WPF.

I fought this for at least ten hours trying to shoehorn various tools into working. All of them almost worked, but none of them actually did. It was a gigantic rabbit hole.

Then I tried to brute force it in a different manner, as long as the results would be the same from the user's perspective, but in the end, the individual character width broke the brute force solution (as it had with different brute force solutions previously).

DQ Visual Basic Advisor Garret Rempel is extraordinarily patient in these situations, trying to assist me in navigating through the shoals of my own stupidity. He gives hints like a good adventure game--starting out at a high level, then getting progressively more specific if I'm still unable to get something working.

This time, I went through Elisabeth Kübler-Ross's entire Five Stages of Coding, and finally he sent one specific line of code (it was a long line, though) that made the one bit work that I needed. Then everything else worked fine. I'd had the right concept, and had everything modeled correctly, but without that one line, it was just a pile of wonky bits.

Once that worked, though, everything started going very quickly. Fredrik finished the retirement image, so after 30 seasons now, the coach (you) retires (with a customized headline, depending on how the team did in those 30 seasons), and you see a lovely image of the coach in retirement.

I also added five different halftime band samples, so instead of one crappy one, there are now five selected at random, and they're all a big upgrade. There's also a tremendous "blah blah blah" version of the Canadian national anthem, if you're playing at home in the Championship game.

Initial team ratings have also been revised to give individual teams more distinctive styles, and they also more closely reflect the spread of team ratings after a full 30-year franchise.

The to-do list is down to fourteen items, which is the lowest it's been in quite a while.


Site Meter