Change the color of selection in a textfield

by ericlin

Selection in textfield is always displayed as white on black. There are no options or properties available for the colors used to display the selection. The colors are always black and white.

Now, we have a problem. What if we want a textfield with white textcolor and black background ?

In such case, normal text is displayed the same as selected text. We can not see our selection.

See the movie above. The first one is a selectable input textfield. You can make selection by dragging the mouse. The background color is "dark brown", you can see faintly what you have selected. If I make the background completely black then you will not be able to see the selection because the selection is displayed white on black, the same as un-selected text.

Now, check the second textfield. I have changed the colors used to display the selection. It is black on white rather than white on black now. It is easy to see what the selection is.

How can I change the selection colors ?

OK, the trick is Color.setTransform. I set a transform. Black color is transformed to white. White color is transformed to dark brown.

0x000000 -->transform -->0xFFFFFF

0xFFFFFF -->transform -->0x330000

Now we need Math to calculate the transform data - the ra,rb,ga,gb,ba,bb.

Lets see the red element of a Color value. The same is true for green and blue elements.

Assume R0 is the red value before color transformation and R1 is the red value after color transformation. The equation is : R0*ra/100+rb=R1;

Black is transformed to a specific color, (here is "whtie") -> rb, gb, bb;

Black color has an original red value as 0. So, the equation can be simplified to rb=R1. The value of ra does not affect the transformed result of BLACK color.

So we get rb.

White is transformed to a specific color, (here is "dark brown") -> ra, ga, ba;

For white color , the original red value R0 is 255; So, the equation is:
ra=(R1-rb)*100/255;

Since we know R1 and rb, we get ra from this equation.

So, it is simple to supply a color transform to make Selection displayed by the two colors we want.

Wait a minutes !

We get one problem after setting color transformation. Yea, the white/black colors are transformed to darkbrown/white to show the selection. But, the original white color text is also get transformed into darkbrown color !  I want my text color remain "white"; How can I make the textcolor resist the color transformation ?

Oh, no, no way to make it resist transformation. However we can find a color that will be transformed to "white". What color will be transformed to "white" ?

Remember what we have done ? The answer is "Black". We have transform the black color of selection into "white". So, we just set the textcolor to be "black". The textcolor will be transformed to "white" then.

So, basically, the script contains 4 procedures.

1. set text color to black; (backup the original textcolor);

2. calculate rb, gb, bb to transform "black" to the original value of textcolor. (here is "white");

After transformation, the black textcolor and the black background of selection will be transformed to the original color value of the textfield.

3. set background color to white; backup the original color value of background. (here is "darkbrown");

4. calculate ra, ga, ba to transform "white" to the original color value of background color("dark brown").

After transformation, the white background and the white selected textcolor will be transformed to the original color value of the textfield.

In my script, I pick the first color by Textfield.textcolor and the second color by Textfield.backgroundColor. However, a textfield may have no background color. In such case, we still need to pick a value to display the textcolor of selected text.

So, anyway, my script open a parameter "background color" to set.

Further note:

It is handy to display selection by opposite colors. So, a textfield of black-on-white will have a selection white-on-black. The "contrast" effect is the same for both unselected and selected text.

If a textfield is yellow-on-red then the selection will be red-on-yellow. Basically, this is a transform effect from a black-on-white box.

A more complex question will be :

Can we have a textfield displayed yellow-on-red but a selection displayed green-on-blue ? Well, we have the transform equation, ra, rb and the desired red value R1, we can easily calculate what original red value R0 should be.

R0=(R1-rb)*100/ra;

So, we set the original red value R0. After color transformation , the result will be R1.

Unfortunately, the R0 calculated by the equation above might be a negative value or a number larger than 255; It is an invalid red value. We can not set a color with an invalid red value.

So, it is not always possible to set the third and fourth color as we wish.