Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Advanced Color Imaging on the Mac OS /
Chapter 2 - Color Picker Manager / Writing Your Own Color Pickers


Returning and Setting Color Picker Information

The Color Picker Manager sends the kGetColor code to request your color picker to supply an original or a new color. In turn, your color picker returns either the original color or the new color, as shown in Listing 2-24.

Listing 2-24 Returning the original or the new color

pascal ComponentResult MyGetColor(PickerStorageHndl storage,
                          ColorType whichColor, 
                          PMColorPtr color)
{
   /* copy the color here because the profile is always set as 
      we want it to be (nil - the system profile/RGB space) */
   if(whichColor == kNewColor)
      *color = (*storage)->color;
   else
      *color = (*storage)->origColor;
   return noErr;
}
Similarly, the Color Picker Manager sends the kSetColor code to request your color picker to set an original or a new color. Listing 2-25 shows how a color picker can set these colors.

Listing 2-25 Setting colors

pascal ComponentResult MySetColor(PickerStorageHndl storage, 
                          ColorType whichColor, PMColorPtr color)
{
   Boolean  updateEditor = false;
   Boolean  textInvalid = false;
   CWorld   cworld;
   PMColor  myColor;
   long     csLong;

   OSErr    err = noErr;
   myColor = *color;    /* get your own copy */
   /* check whether a profile was included; if so, convert the color to 
      system space */
   if(color->profile)  
   {
      /* first ensure that ColorSync is available */
      if(Gestalt(gestaltColorMatchingVersion,&csLong) != noErr)  
      {
         err = colorSyncNotInstalled;
         goto fail;
      }
      /* create the color world and convert the color */
      if(CWNewColorWorld(&cworld,myColor.profile,0L) == noErr) 
      {
         if(CWMatchColors(cworld,&myColor.color,1) != noErr)  
         {
            err = badProfileError;
            CWDisposeColorWorld(cworld);
            goto fail;
         }
         CWDisposeColorWorld(cworld);
      } 
      else  
      {
         err = badProfileError;
         goto fail;
      }
   }
   myColor.profile = 0L;   /* it's in the system space now */
   if(whichColor == kNewColor)  
   {
      (*storage)->color = *color;
      (*storage)->lastRGB = color->color.rgb;
      updateEditor = true;
   } 
   else  
   {  (*storage)->origColor = *color;
      /* make a new pattern for the original color */
      MakeRGBPat((*storage)->origColorPat,&color->color.rgb);
      if((*storage)->visible)
         DrawMYColorRects(storage,true);/* redraw original color rect */
   }
   if(updateEditor)  {
      /* make some calls to update data structures and redraw the parts of 
         the picker that need to be redrawn */
      SetSelectionColor(storage);
      UpdateColorText(storage);
      if((*storage)->visible)  
      {
         /* you don't call DoPickerDraw here because you don't need to 
            redraw everything */
         DrawMYColorRects(storage,false);
         DrawMYColorEditor(storage,false);
      }
   }
fail: C
   return err;
}
Listing 2-26 illustrates a color picker-defined function that responds to the kGetIconData request code. The color picker uses a PickerIconData structure (described in "Color Picker Manager Reference" in Advanced Color Imaging Reference) to return the script code and the resource ID of the icon family by which the color picker identifies itself in the list of icons for available color pickers in a color picker dialog box. (Such an icon list is shown in Figure 2-2.)

Listing 2-26 Returning icon data

pascal ComponentResult MyGetIconData(PickerStorageHndl storage, 
                            PickerIconData *data)
{
   short             fref;
   OSErr             err = noErr;
   PickerIconData    **mypdat;

   data->scriptCode = 0;
   data->iconSuiteID = kPickerData;
   fref = OpenComponentResFile((Component) (*storage)->myself);
   if(fref)  
   {
      mypdat = (PickerIconData **)GetResource(kPickerDataType, 
                                             kPickerData);
      if(mypdat)
         *data = **mypdat;
      else
         goto fail;
   } 
   else
      goto fail;
   CloseComponentResFile(fref);
   return err;
fail:
   DebugStr("\pProblem getting resource");
   return pickerResourceError;
}
The Color Picker Manager sends the kGetPrompt request code to obtain the prompt string currently used by your color picker. Your color picker should respond to this code by returning its string, as illustrated in Listing 2-27.

Listing 2-27 Returning the color picker's prompt

pascal ComponentResult MyGetPrompt(PickerStorageHndl storage, 
                           Str255 prompt)
{
   Handle   theItem;
   short    iType;
   Rect     iBox;

   GetDialogItem((*storage)->port, (*storage)->baseItem + 
                  iPrompt, &iType ,&theItem, &iBox);
   GetDialogItemText(theItem, prompt);
   return noErr;
}
Listing 2-28 illustrates a color picker-defined function that responds to the kSetPrompt request code by setting the prompt string used by the color picker.

Listing 2-28 Setting the color picker's prompt

pascal ComponentResult MySetPrompt(PickerStorageHndl storage, 
                           Str255 prompt)
{
   Handle theItem;
   short iType;
   Rect iBox;

   GetDialogItem((*storage)->port, (*storage)->baseItem + 
                  iPrompt, &iType, &theItem, &iBox);
   SetDialogItemText(theItem, prompt);
   return noErr;
}
The Color Picker Manager sends the kGetProfile request code to obtain the destination color-matching profile currently used by your color picker. Your color picker should respond to this code by returning the destination profile, as illustrated in Listing 2-29.

Listing 2-29 Returning the destination profile

pascal ComponentResult MyGetProfile(PickerStorageHndl storage)
{
   Handle h;
   h = (Handle) (*storage)->profile;
   if(h)
      HandToHand(&h);
   return (long) h;
}
Listing 2-30 illustrates a color picker-defined function that responds to the kSetProfile request code by setting a new destination profile for use by the color picker.

Listing 2-30 Setting the destination profile

pascal ComponentResult MySetProfile(PickerStorageHndl storage, 
                           CMProfileHandle profile)
{
   CMProfileHandlemyProfile;

   OSErr err = noErr;
   /* Make a private copy of the profile, even though this 
      picker doesn't do anything with profiles. This is necessary 
      because the Color Picker Manager relies on color pickers to 
      store this data so that it doesn't have to duplicate the 
      storage and waste memory. */
   if(myProfile = profile)  
   {
      HandToHand((Handle *) &myProfile);
      if((err = MemError()) != noErr)
         goto fail;
   }
   (*storage)->profile = myProfile;
fail:
   return err;
}
The Color Picker Manager sends the kGetEditMenuState request code to obtain information about the desired state of the edit menu for your color picker. As illustrated in Listing 2-31, your color picker should respond to this code by returning edit menu information in a MenuState structure, which is described in detail in "Color Picker Manager Reference" in Advanced Color Imaging Reference.

Listing 2-31 Specifying how the Edit menu should be set

pascal ComponentResult MyGetEditMenuState(PickerStorageHndl storage, 
                                MenuState *mState)
{
   #pragma unused(storage)
   OSErr err = noErr;
   mState->cutEnabled = true;
   mState->copyEnabled = true;
   mState->pasteEnabled = true;
   mState->clearEnabled = true;
   mState->undoEnabled = true;
   strcpy(mState->undoString,"\pUndo");
   return err;
}

Previous Book Contents Book Index Next

© Apple Computer, Inc.
13 NOV 1996