Back to top
Color Picker 2.1 APIs
To download new header files click here.
In Apple's studies, we realized
that a majority of the Color Picker APIs were not being used
by developers. Therefore, with the Color Picker 2.1 release,
a lot of the APIs have become obsolete. This section covers
new, old, supported and unsupported/removed APIs. If you
have a need for one of the obsolete APIs, please let
Developer Support know at feedback and we will
attempt to get the API reinstated or give you another way to
implement the same functionality.
Back to top
New API
Here is the one new Color Picker 2.1 call (ColorSync 2
savvy):
pascal OSErr
NPickColor (NColorPickerInfo *theColorInfo );
theColorInfo :
A color picker parameter block, which is described on
page 2-21 of the Advanced Color Imaging Reference. With
Color Picker 2.1, however, where profile handles were used
with Color Picker 2.0, profile references are nowused for
this API.
DESCRIPTION
This call is identical to PickColor() , but it replaces the older
ColorSync 1.0 data types with new ColorSync 2.x profile
references. The color picker parameter block is described on
page 2-21 of the Advanced Color Imaging Reference.
When filling out the parameter block for a call to NPickColor , replace all profile
handles with profile references. The optional color-changed
proc you has also changed; a new data structure NCMColor replaces the
CMColor data type and uses profile
references. See the "New Component Manager Messages" section
for more information on the color-changed proc.
Back to top
Maintained APIs
Here are the original Color Picker 1.0 calls that we are
keeping and maintaining:
pascal SmallFract Fix2SmallFract(Fixed f);
pascal Fixed SmallFract2Fix(SmallFract s);
pascal void CMY2RGB(const CMYColor *cColor, RGBColor *rColor);
pascal void RGB2CMY(const RGBColor *rColor, CMYColor *cColor);
pascal void HSL2RGB(const HSLColor *hColor, RGBColor *rColor);
pascal void RGB2HSL(const RGBColor *rColor, HSLColor *hColor);
pascal void HSV2RGB(const HSVColor *hColor, RGBColor *rColor);
pascal void RGB2HSV(const RGBColor *rColor, HSVColor *hColor);
pascal Boolean GetColor(Point where, ConstStr255Param prompt, const RGBColor *inColor,
RGBColor *outColor);
|
Here is the one Color Picker 2.0 call we are keeping and
maintaining:
pascal OSErr
PickColor (ColorPickerInfo *theColorInfo );
NOTE: Please see the "Advanced Color Imaging" book for
complete details on these APIs.
Back to top
Obsolete APIs
Here are the Color Picker 2.0 and 2.1 calls we have
removed:
AddPickerToDialog
CreateColorDialog
CreatePickerDialog
DisposeColorPicker
GetPickerVisibility
SetPickerVisibility
SetPickerPrompt
DoPickerEvent
DoPickerEdit
DoPickerDraw
GetPickerColor
SetPickerColor
GetPickerOrigin
SetPickerOrigin
GetPickerProfile
SetPickerProfile
GetPickerEditMenuState
SetPickerColorChangedProc
NCreateColorDialog
NGetPickerColor
NSetPickerColor
NGetPickerProfile
NSetPickerProfile
NSetPickerColorChangedProc
ExtractPickerHelpItem
|
If you have a need for one of these APIs, please contact
feedback.
Back to top
Eye Dropper Tool
For a picker developer, the eye dropper tool is probably
the single-most significant addition to Color Picker 2.1. If
the user holds down the Option key, the cursor will change
to an eyedropper and the user will "pick up" the color under
the cursor. This section describes how this feature is
implemented and how your application can take advantage of
it.
Back to top
Overview
The way this tool was created is rather straightforward,
but is a little tedious to explain. Recall that beginning
with Color Picker 2.0, color pickers have been component
based (that is, using the Component Manager). Individual
color pickers are loaded and instantiated as the user
browses through them in the Color Picker dialog. The way the
Color Picker Manager interacts with the individual color
picker components is through Component Manager-based
messages. The Color Picker has defined many messages for
things such as passing events to the picker, telling the
color picker to redraw itself, telling the color picker to
set the "new" color, etc. In terms of the eyedropper tool,
two messages are particularly important: the PickerEvent message and the
PickerSetColor message.
In Color Picker 2.0, the individual pickers were sent
only two PickerSetColor messages
after instantiating the picker. These were to tell the
picker how to set both the original color and new color
boxes. The original color was the color originally passed in
when the application first called upon the color picker, the
new (or user) color was the current color the user had
selected. After a color picker had received these messages
(and others as well) and displayed itself, the PickerEvent message came to the
forefront. In fact, until the user clicked on another color
picker or hit the okay or cancel button, a color picker
basically remained in an event loop, receiving events from
the Color Picker Manager via the PickerEvent message. Even null events
were passed along to the color pickers ( this was an ideal
time for a color picker to update the cursor, etc.).
In Color Picker 2.1, things have changed a bit. First of
all, you can no longer be assured that your picker will
receive only the initial two PickerSetColor messages. When a user
holds down the option key (invoking the eye-dropper tool)
and clicks, the Color Picker Manager now suppresses that
click from the current color picker and instead sends it a
PickerSetColor message. The
color picker sends this message with the user color flag set
thus, the original color will never change. For a
color picker to be savvy with 2.1, it needs to be able to
handle the odd PickerSetColor
message and handle the new color passed it. This includes
updating the user color box in the upper right corner of the
picker to display the new color, updating whatever sliders
and text edit fields the color picker has, etc. Try it out,
all the Apple color pickers do this correctly.
Back to top
Instructions and Warnings
1. The Color Picker Manager may change the cursor on you
(to the eyedropper cursor). It is the picker's
responsibility to change it back. If your color picker is
handling cursor updates during null events, you need do
nothing more. One third-party picker was doing no cursor
updating at all this would leave the cursor as an
eyedropper even though the user had let up on the option
key. A well-written color picker will always handle cursor
updating for example, when the user moves the
cursor over a text edit field the cursor should turn into an
I-beam cursor, etc.
2. Since color pickers should be handling cursor updating
during null events, all null events are suspended while the
option key is held down. If this were not the case, there
would be a sort of tug-of-war between the Color Picker
Manager and the individual color pickers the
Color Picker Manager would be fighting to set the cursor to
an eyedropper while the picker was trying to set it to an
arrow or whatever.
3. Finally, recall also that the Color Picker can be
called moveable modal (using the more mid-level API calls
like PickColor() ) as well as
standard modal (using the higher-level API call GetColor() ).
There is an interesting
side-effect then for these two cases. If the picker is
called moveable-modal (think fast now) what would be the
effect of option-clicking, say, in the Desktop while the
picker is up? Well, the Event Manager snuffs the
Option-Click and instead switches the user out of the
current application, hides the current application, and
switches the user into the Finder. In fact, Option-Clicking
in any other process's windows will cause a similar behavior.
Rather than breaking that "user experience", we preserve it.
So, the only time that the user actually gets an eyedropper
cursor is when 1) the option key is down and 2) the cursor
is over one of the current process's windows! By and large,
this is as you would want it. If you were writing a paint
program and wanted the user to be able to pick up a color
using the Color Picker from their document, this document
window would of course be a window owned by your
application. Also, if the Color Picker were called
moveable-modal, the user would of course be able to move the
Color Picker's dialog around on the screen so as to get at
that specific color that they want from their document.
The strictly modal case is quite another situation. Since
it is a non-moveable modal dialog, there never was any
context switching behavior to preserve. In fact, the only
thing the user would expect from clicking in the Desktop
from a modal dialog is a SysBeep() sound (indicating, "Don't
do that!". Well, Color Picker 2.1 preserves the SysBeep()
scenario except when the option key is down. When the option
key is down, the user can click anywhere (except the menu
bar) and pick up a color even from the Desktop or
another process' window. The down side of course, is that the
dialog is not moveable. So if the color the user wanted to
pick up was underneath the Color Picker's dialog
too bad.
By the way, the Color Picker handles
all the hit-testing etc. by building the hit-test region
so that when the cursor is within
this region and the option key is down, they get an
eyedropper; otherwise they don't. For the moveable-modal
case, we walk the current layers window list accumulating
window regions. In the strictly modal case, we use GetGrayRgn() .
Finally, make sure you update the cursor during null
events passed your picker and also be able to handle PickerSetColor
messages at any time.
The eyedropper tool is otherwise free working
across all color pickers and requires no additional work on
your part; (most third-party color pickers work
perfectly without modification).
Back to top
New Component Manager
Messages
For new header files click here.
If you wish to write a Color Picker component or if you
wish to revise a Color Picker component you have already
written, there are some new Color Picker messages you may
want to implement.
PickerSetColorChangedProc
pascal ComponentResult
PickerSetColorChangedProc (long storage, ColorChangedUPP
colorProc, long colorProcData )
This message is sent once to your picker, after you are
called to initialize yourself. It contains a procPtr to the
calling applications colorChangedProc . This allows you, the
picker, to call the applications colorChangedProc directly.
This was found useful during times when the picker is
stealing all events - for example, during a drag of a slider
when the user has the mouse button continuously down. When
the user releases the mouse button, control returns to the
Color Picker Manager and the colorChangedProc is called at
that time. But you may, in your picker, want to call the
colorChangedProc yourself while the user is "live dragging".
Continually calling the colorChangedProc can slow you way
down however, depending on how processor intensive the
colorChangedProc is. Therefore, the new Color Picker defines
a new flag in the flags field passed in by the calling
application: kColorPickerCallColorProcLive . Your picker is
passed a copy of the flags when the Color Picker Manager
sends your picker a PickerInit message. Therefore, it is
recommended that if you support the
PickerSetColorChangedProc message you should:
1) Call it only during mouse drags when the Color Picker
Manager is unable to get processor time to call the
colorChangedProc .
2) Call it only if the kColorPickerCallColorProcLive flag
is set.
NPickerGetColor ,
NPickerSetColor ,
NPickerGetProfile ,
NPickerSetProfile ,
and NPickerSetColorChangedProc
pascal ComponentResult
NPickerGetColor (long storage, ColorType whichColor, NPMColor
*color
pascal ComponentResult NPickerSetColor(long storage,
ColorType whichColor, NPMColor *color)
pascal ComponentResult NPickerGetProfile(long storage,
CMProfileRef *profile)
pascal ComponentResult NPickerSetProfile(long storage,
CMProfileRef profile)
pascal ComponentResult NPickerSetColorChangedProc(long
storage, NColorChangedUPP colorProc, long
colorProcData)
These messages are simply parallel to the original Color
Picker 2.0 messages. They however pass profile references
where their original Color Picker 2.0 counterparts passed in
profile handles. This reflects the ColorSync 2.x support.
Please see the "Advanced Color Imaging" book for more
information on the 2.0 messages.
Color Picker Component Manager
Message Warnings
Recall that a component has only a single "main" entry
point and that the Component Manger sends your component
messages via this entry point. Typically, you would have
something like a big case statement in your "main" function.
Based upon the message, you would either call out to your function or
return badComponentSelector (0x80008002) if you receive a message value
that you don't understand. Please see Inside Macintosh: More Macintosh Toolbox
for more information on the Component Manager and badComponentSelector.
If you choose not to implement all the new Color Picker messages, you
must return badComponentSelector for all the messages that you do not
support. This allows the Color Picker Manager to handle the message in
some other fashion.
Also, please note that there is a standard Component
Manager message "kComponentCanDoSelect ". This also is an
important place to respond to the Color Picker Manager that,
"Yes, I know what how to handle that message," or "No, I
don't.". It is important to do this so that the Color Picker
does not try to work around your application.
Back to top
References
Advanced Color Imaging on the MacOS
Inside Macintosh:Macintosh Toolbox Essentials
Inside Macintosh:More Macintosh Toolbox
To download the Color Picker 2.1 SDK and Sample code click here.
Back to top
Downloadables
|
Acrobat version of this Note (XXX K).
|
Download
|
Back to top
|