Although
you will probably choose an attractive color scheme for your GUI
applications, the user's satisfaction with the application may be
greatly improved by allowing them to choose the colors used for the
major screen objects. By using the ColorPick pseudo object you allow the
user to efficiently choose the screen colors in a consistent way within and
among your applications. Also, you will find that selecting colors using the
ColorPick figure is much easier than using the typical Windows style
palette which attempts to show all possible colors in a single palette.
I've found you need to see a fairly large area of your potential color choice
before you can decide if the color is suitable. It is not possible to accomplish
that using a single palette which is what makes it frustrating to use. By allowing
you to fix one of the colors, ColorPick presents an 11x11 palette of choices
for the remaining two colors which gives you plenty of area for each color block.
(If that is not enough, you can resize the ColorPick figure to be as large as you want.)
Even more important is that the instant you click on one of the 121 colors in the
current palette the larger patch above the palette AND the objects in the gui that you are
adjusting instantly change to the selected color. This instant feedback is really
necessary to remove the frustration that usually arises from the task. Scrolling through the
many possible palettes is also very quick. Just pick any slider and click on the
left/right arrows for a finely changing palette, or click in the trough area of
the slider for a more coarsely changing palette (which should be fine enough all
but the most picky color chooser).
Any Matlab object that has either a callback property or a buttondownfunction
property may be used to bring up the ColorPick window shown here. Before I describe
how this is done from a programming perspective I will give a few more details about
how the user selects colors from this window.
The text above the sliders is generally used to identify the object or
objects that are to receive the color being selected. The three sliders
always indicate the RGB values of the currently selected color. In the example
shown at the left, the RGB values are
35%, 80%, and 60% respectively. In Matlab, this color would be represented
by the vector [0.35 0.8 0.6]. The large rectangular patch object
in the upper right corner always indicates the color that results when the
proportions are set to agree with the values of the three RGB sliders. One
of the sliders (the red one in this example) will always be shown with its
text value in yellow and is referred to as the "active slider". A slider
will become the active slider whenever you either type in a value into its
edit box or when you click on the left or right slider arrows. There are 3
ways to alter the currently selected color:
You can simply select the desired color using the RGB sliders. Note that
with this method it is irrelevant which slider is identified as active.
You can click on any one of the 121 small square patches that are arranged in an 11x11 grid.
The colors in this grid are entirely determined by the active slider. In this
example, since the active slider shows RED=35%, every color in the 11x11
color grid will have red = .35 with varying amounts of the other two colors.
So in this example, the colors of the 4 corners of this grid starting at
the lower left and moving clockwise are:
[.35 0 0], [.35 1 0], [.35 1 1], and [.35 0 1]. and the square exactly in
the middle of this grid has the color [.35 .5 .5]. Clicking on any one of
these 121 patches will change the two inactive sliders to the values
associated with the patch that you clicked on. (The active slider will be
unchanged and will remain active). Also, the large patch and all the objects in the
gui that are associated with this ColorPick object will change to show the new selected color.
Clicking on the large patch will cause the
sliders to move to the "reset" values - i.e. the color that was in effect
when the ColorPick window was first opened. Note that this color never
changes for as long as the ColorPick window remains open. The reset values
may be changed to the values shown currently by the sliders by closing the
ColorPick window and re-opening it again.
Next, I will describe how the ColorPick object is created from the programmer's viewpoint.
I will call the object that initiates the creation of the ColorPick figure window the
"main object". You must do the following two things to make a ColorPick
figure appear:
You must assign one of the following strings To the callback or buttondownfunction property (or both)
of the main object :
'plt ColorPick' This will cause the ColorPick
figure to be created when the callback or buttondownfunction is called
except for one special case - which is when the callback of an 'edit' style
uicontrol is called. The reason for this special case is that if you type
the desired colors directly into an edit box usually this indicates that you
didn't need the help of the ColorPick figure.
Note that in this special case, the properties listed in the 'm' application
data cell array are still modified as described above even though the
ColorPick figure is not created. Note that the ColorPick window will appear
when you right-click on such an edit box if the buttondownfunction of the
edit box has been similarly assigned.
'plt ColorPick ccf' This has the same effect as above
except that when the user changes a color with the ColorPick figure, in
addition to changing the properties in the 'm' cell array, the function
ccf is called. ccf stands for color change function and may be any string
corresponding to a function name and may include numerical arguments, such as
in 'plt ColorPick changeFunc(3,-1)'. In fact, the function can have string
arguments as well although this is less convenient since you would need
two sets of quotes around each string argument. For example
'plt ColorPick changeFunc(''StringArg'')'. You should especially avoid color
change functions that required a string argument containing spaces
although if you really wanted to do that it would be possible with an
obscure-looking callback such as
'plt(''ColorPick'',''changeFunc(''''A string argument'''')'')'
'plt ColorPick 0 0' is similar to case 1 above and
plt ColorPick ccf 0' is similar to case 2 except that
the special case relating to the edit box callback does not apply (i.e. the ColorPick window will be
created in every instance).
Usually when you select a color from the ColorPick figure, this color is applied to either
the 'Color' property of the main object or (if the main object does
not have that property) to the 'BackGroundColor' property.
However often you will want to apply the color to different properties as well as to different
objects. To do this you must assign an application data variable named
'm' to the main object with a cell array of this form:
{'PROP1', H1, 'PROP2', H2, 'PROP3', H3, ... 'PROPn', Hn, 'label'} When the user selects a new color using the
ColorPick figure, the 'PROP1' property of the object with handle H1 will be
set to the 3 element vector [R G B] where RGB are the values from the
ColorPick figure. If H1 is a row vector of handles, each of the represented
objects will be treated similarly. Then in sequence the objects in H2, H3
... Hn are treated in a like manner. If any of the 'PROPi' entries are
'str' or 'string', then the numerical 3-element color vector is converted to
an Ascii string before being assigned to that property. In place of any property
string, you may use a cell array of strings in which case ColorPick will assign
the user-selected color to all the properties listed in the cell array of all
the handles listed in the following argument. Finally, the
last entry 'label' is optional, and if included will appear above the rgb
sliders and is used to identify what screen elements are being controlled.
Only one detail remains to describe the operation of the ColorPick object,
and that has to do with how ColorPick determines the starting positions of
the RGB sliders when the window is first opened. It's very simple when the
'm' appdata is not defined, since in that case
the initial color will be the same as the color of the main object (either
its 'Color' or 'Backgr' properties depending on which property it has.)
When the 'm' appdata is defined, this is a two-step
process. First ColorPick must decide which object will be used to determine
the initial color. Once the object is chosen, ColorPick must decide which
property of this object to use. Here are the details of these two steps:
Picking the object which will determine the initial color. Usually the
handle of the main object will be among one of the handles included in the
'm' application data cell array and in this case the main object itself is
used to determine the initial RGB slider positions. However, sometimes this
is not the case. For example, in the demoplt.m program, we would like to
open the ColorPick window when we click on the text object "text color"
which serves as a label for the text color patch. However since this is just
a label, it is not entirely appropriate for the color of this text object to
change which means that it will not appear in the list of handles in the 'm'
cell array. So in this instance, ColorPick determines the initial color from
the object whose handle is the first element of H1 in the 'm' cell array.
(This is the only instance where the order of the handles in this array is
significant.)
Picking the property of the selected object that determines the initial color.
If the selected object is a uicontrol. If
the uicontrol is an edit box then its 'string' property is always used to
determine the initial color. If the string includes fewer than 3 numbers,
then extra zeros are added to the end of the vector. If the string includes
any numbers that are greater than one, then these numbers are clipped at one
and if any numbers are less than zero, then these numbers are clipped at
zero. If the uicontrol is not an edit box, then first the 'string' property
is examined to see if it represents a valid color vector (i.e. it must have
3 elements, all of which are between 0 and 1). If it is valid, then this
vector is used as the initial color. If it is not valid, the uicontrol
'backgroundcolor' property is used as the initial color.
If the selected object is a text object, its 'string' property is used if this
string translates to a valid color vector. Otherwise the 'color' property of
the text object is used.
If the selected object is a patch object, its 'facecolor' property is used as the
initial color.
For all other object types, the 'color' property is used as the initial color.
While all this sounds quite complicated, using ColorPick is usually not that difficult
because in most cases it does what you would expect. It may be easier just to look at some
examples of ColorPick in action which you can do in the following programs:
demo folder:
demoplt pub0 trigplt vbar
math folder:
gpsLog
sig folder:
afilt
util folder:
pltpub
In the simplest cases, the 'm' appdata may not needed
(for example in gpsLog.m, vbar.m, and
and trigplt.m). The remaining examples use the
'm' appdata to tailor how the ColorPick pseudo object is used.