TOPIC: A New HightlightControl
A New HightlightControl 1 Year, 7 Months ago
Here is another UI change I have been thinking about for a while.

Often a screen has some "important" settings that it would be nice to "highlight" when they are set.

So I wrote HighlightControl to do this. It only works inside a RecordControl and when you are specifying fields by name.

For example, instead of:

(Form field1 field2 field3)

you can write:

(Form field1 (Highlight field2) field3)

HighlightControl is similar to MainFieldControl. They both change the appearance of the prompt, but Highlight is based on the value of the field, whereas MainField just statically changes the prompt.

Here is a screenshot with a bunch of fields highlighted. As you can see, the color is configurable. By default the prompt is highlighted if the field is not empty or false. But you can also configure it to highlight the prompt if the field has a specific value.

Because our screens do not use much color, the highlight stands out quite well. (Normally you would not be highlighting as many fields as in this example.)

This was fairly simple to implement. One problem was catching all the changes to the field. For some reason RecordControl observers are not notified by Set. I wrote one version using a timer to check for changes, but that seemed ugly. I ended up using an observer, plus registering as data in order to catch Set's.

The other problem was that it changes the prompt to bold, which changes the size, which means you have to recalculate the screen layout. .Window.Refresh is supposed to do that, but it does not handle all cases. In a few places we also call .Window.BottomUp(#Recalc) I knew that Window.Refresh should probably be calling Recalc but I was afraid of breaking anything. So I "took the plunge" and moved Recalc into Window.Refresh. In some places we were also using Delayed(0 so the current operation finished before the refresh. So I moved this into Window.Refresh as well. This also allowed merging multiple calls. I ended up with:


refreshing?: false
    if .refreshing?
    .refreshing? = true
    Delayed(0, .refresh)
    .refreshing? = false
    GetClientRect(.Hwnd, rc = Object())
    .SIZE(rc.right | (rc.bottom << 16))

So far it seems to be working well, but it is always dangerous making these kind of low level changes. We will have to use it for a while to make sure it has not broken anything.
Last Edit: 2008/12/27 00:37 By andrew.