 |
Technote 1100
Color Picker 2.1
Color Picker 2.1 の概要
Color Picker Manager は、ユーザに色の選択を要求するための機能と標準ユーザインタフェースをアプリケーションに提供します。アプリケーションではこれらの
API を使って“Color Picker”機能拡張との間で情報をやり取りすることができます。また、独自のカスタムカラーピッカーを作成することも可能です。
必要なシステム構成
- Color Picker 2.1 は System 7.5 から Mac OS 8.0 までのシステム上で実行されます。
依存関係
- QuickTime Component Manager: Color Picker 2.1 は QuickTime がインストールされていれば
QuickTime Component Manager を使用します。ただし、Color Picker Manager は独自の Component
Manager のコードをロードします。
-
- ColorSync: ColorSync がインストールされていれば (必ずしも必要ではありませんが)、Color
Picker Manager は ColorSync を使用します。Color Picker 2.1 には、ColorSync 2.x システム特性のサポートが追加されています。
ライセンス
- Color Picker 2.1 については、ColorSync addendum の一部として Apple の Software
Licensing グループからライセンスを受けることができます。製品とともに Color Picker
を出荷するには、Color Picker のライセンスを取得する必要があります。ライセンスの詳細については、Apple
の Software Licensing グループ (1-512-919-2645 または sw.license@apple.com)
までお問い合わせください。
ダウンロード
Gestalt
Gestalt() をチェックすることで、gestaltColorPickerVersion
セレクタを使って Color Picker 2.1 が存在するかどうかを判定することができます。Gestalt()
の戻り値がエラーになる場合、バージョン 1.0 の ROM ベース Color Picker が存在しています。戻り値が
0x00000100 の場合は Color Picker 2.0 (ちょっと不気味ですが、本当の話です)
が、戻り値が 0x00000210 になる場合は Color Picker 2.1 が使用可能です。
新機能
- 新しいシステムカラーピッカー (“CMYK ピッカー”、“Crayon ピッカー”、“HSV ピッカー”、“HTML
ピッカー”)。詳細については、後述の「新しいカラーピッカー」を参照してください。
- Color Sync 2.x システム特性のサポート。
- スポイトツール。詳細については、後述の「スポイトツール」を参照してください。
- よりコンパクトになった API。概要については、後述の「Color Picker
2.1 の API」を参照してください。
- Power PC ネイティブのピッカー。
新しいカラーピッカー
Color Picker 2.1 には新しい 4 つのピッカーが用意されています (“CMYK ピッカー”、“Crayon
ピッカー”、“HSV ピッカー”、“HTML ピッカー”)。ここでは、これらの新しいピッカーの概要を説明し、その外観を示します。
CMYK
これは、スライダを使って CMYK 色空間にある色を選択するためのピッカーです。大部分の出力デバイスはこの色空間を利用しているため、このピッカーは主としてカラープリプレス業界で使用されることを想定しています。

Crayon
“Crayon”ピッカーは、ホームおよび教育市場をターゲットにしています。このピッカーには
60 色のクレヨンが表示され、ユーザはその中から好きな色を選ぶことができます。

HSV
オリジナルの Color Picker 1.0 (Apple では愛情をこめてダーツ盤と呼ばれています) は
1種の HSV ピッカーでした (これは Hue (色合い)、Saturation (彩度)、Brightness (明るさ)
を指定するピッカーという意味です)。このピッカーはバージョン 2.0 で一度削除されましたが、このピッカーの復帰を望むユーザの多いことが判明しました。このため、従来の色の選択に満足しているユーザのために、Apple
では Color Picker 2.1 に再度 HSV ピッカーを追加しました。このピッカーは、オリジナルの
1.0 ピッカーとほぼ同じ "ホイールとスライダ" のインタフェースを持ちます。

HTML
これは基本的にはスライダベースの RGB ピッカーです。ただし、設定単位は 16 進のバイトで、HTML
タグに使用する RGB 値が 4 番目のテキスト編集フィールドに表示されます (赤色に対するスライダの値が
99、緑色に対する値が 66、青色に対する値が CC の場合、“HTML”フィールドには "#9966CC"
という値が表示されます)。多くの HTML コマンドでは、オブジェクトの色を指定するためにこのフォーマットの
16 進 RGB 値を必要とします。

ピッカーがインストールされているかどうかの判定
デベロッパは、特定のピッカーがユーザのマシンにインストールされているかどうかを知りたい場合があります。このような判定を行うには、次の
2 つの処理を実行する必要があります。
1. Gestalt セレクタの gestaltColorPickerVersion の値をチェックします。
theErr = Gestalt(gestaltColorPickerVersion, &value);
2. この後、Component Manager を使って、特定のタイプのピッカーを対象とするクエリーを実行します。すべての
Apple カラーピッカーでは、メーカータイプ 'appl'、タイプ 'cpkr'、およびピッカーの色空間を反映したサブタイプを使用しています
(ColorSync の CMApplication.h ヘッダファイルで定義されているように)。
次に、さまざまなカラーピッカーに対応するサブタイプを示します。
CMYK ピッカー = cmCMYKData = 'CMYK'
Crayon ピッカー = none = 'name' (Pantone などの "名前付き色空間"
に対する名前です)。
HLS ピッカー = cmHLSData = 'HLS'
HSV ピッカー = cmHSVData = 'HSV'
HTML ピッカー = none = 'HTML'
RGB ピッカー = cmRGBData = 'RGB '
たとえば、ユーザのシステムに Apple の CMYK ピッカーが存在するかどうかを確認するには、ComponentDescription
構造体を次のようにセットアップします。
theComponentDesc.componentType = 'cpkr';
theComponentDesc.componentSubType = cmCMYKData;
theComponentDesc.componentManufacturer = 'appl'; |
Color Picker 2.1 の API
新しいヘッダファイルをダウンロードするには、ここをクリックしてください。
これまでの調査で、Apple は、大部分の Color Picker API がデベロッパによって有効に使用されていないという認識を持っています。このため、Color
Picker 2.1 のリリースに伴い、多くの API を廃止しました。ここでは、新しい API、古い
API、今後もサポートされる API、および今後はサポートされないあるいは削除された API
について説明します。今回廃止された API のいずれかを使用する必要がある場合は、Apple
の Developer Support グループ (devsupport@apple.com)
までお知らせください。Apple では、そうした API を復活させる、あるいは同じ機能をインプリメントするための別の方法を提供する準備があります。
新しい API
次に示す新しい Color Picker 2.1 呼び出し (ColorSync 2 savvy) が 1 つだけ追加されています。
pascal OSErr NPickColor(NColorPickerInfo
*theColorInfo);
theColorInfo:
カラーピッカーパラメータブロックです (『Advanced
Color Imaging Reference』の 2-21 ページで説明されています)。Color Picker
2.0 ではシステム特性ハンドルが使用されていましたが、Color Picker 2.1 ではこの API
のために新たにシステム特性リファレンスが使用されます。
説明
この呼び出しは PickColor() と同じですが、古い ColorSync 1.0 のデータ型を新しい
ColorSync 2.x のシステム特性リファレンスに置き換えます。カラーピッカーのパラメータブロックは、『Advanced
Color Imaging Reference』の 2-21 ページで説明されています。NPickColor
を呼び出すためにこのパラメータブロックに値を書き込むときに、すべてのシステム特性ハンドルをシステム特性参照に置き換えてください。オプションの
color-changed プロシージャも変更されました。新しいデータ構造体の NCMColor
は CMColor データ型を置き換え、システム特性参照を使用します。color-changed
プロシージャの詳細については、後述の「新しい
Component Manager のメッセージ」を参照してください。
今後も使用される API
次に示すオリジナルの Color Picker 1.0 呼び出しは、Color Picker 2.1 でも保持され、今後もサポートされます。
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);
次に示す Color Picker 2.0 呼び出しは、Color Picker 2.1 でも保持され、今後もサポートされます。
pascal OSErr PickColor(ColorPickerInfo
*theColorInfo);
注意: これらの API の詳細については、『Advanced
Color Imaging Reference』を参照してください。
今後は使用されなくなる API
次に、削除された Color Picker 2.0 および 2.1 呼び出しを示します。
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
これらの API のいずれかが必要になった場合は、devsupport@apple.com
までお問い合わせください。
スポイトツール
ピッカーのデベロッパにとって、スポイトツールは Color Picker 2.1 の最も重要な追加機能です。ユーザが
option キーを押し続けるとき、カーソルの形がスポイトに変わり、ユーザはカーソルの下にある色を
"ピックアップ" できるようになります。ここでは、この機能をインプリメントする方法と、アプリケーションがこの機能の利点を十分に引き出す方法について説明します。
概要
このツールが作成された方法はどちらかといえば単純ですが、説明を始めるとそれなりに長くなります。Color
Picker 2.0 以降、カラーピッカーがコンポーネントベースになったことを思い出してください
(つまり、Component Manager を使用するようになりました)。それぞれのカラーピッカーは、ユーザが“Color
Picker”ダイアログでそれらをブラウズするときにロードされ、そのインスタンスが起動されます。Color
Picker Manager と個別のカラーピッカーコンポーネントは、Component Manager ベースのメッセージを介して相互に作用します。
Color Picker は、イベントをピッカーに渡したり、カラーピッカーに再描画を指示したり、カラーピッカーに
"新しい" 色の設定を指示したりするために多くのメッセージを定義しています。スポイトツールに関していえば、2
つのメッセージが特に重要です。つまり、PickerEvent メッセージと PickerSetColor
メッセージの 2 つです。
Color Picker 2.0 では、ピッカーのインスタンスが起動された後で、個別のピッカーには
2 つの PickerSetColor メッセージだけが送られていました。これらは、ピッカーにオリジナルのカラーボックスと新しいカラーボックスを設定するための方法を指示するものでした。オリジナルの色とは、アプリケーションが最初にカラーピッカーを呼び出したときにもともと渡されていた色のことです。また、新しい色
(あるいはユーザカラー) とは、ユーザが選択した現在の色のことです。カラーピッカーがこれらのメッセージ
(またその他のメッセージ) を受け取り、自分自身を表示した後、PickerEvent
メッセージが最前線に登場しました。事実、ユーザが別のカラーピッカーをクリックするか、“OK”または“キャンセル”ボタンをクリックするまで、カラーピッカーは基本的に、PickerEvent
メッセージ経由で Color Picker Manager からイベントを受け取る 1 つのイベントループの中に残っていました。null
イベントがカラーピッカーに渡されることさえありました (これはカラーピッカーがカーソルなどを更新するために理想的な時間でした)。
Color Picker 2.1 では事態が多少変わりました。まず何よりも、ピッカーが最初に 2 つの
PickerSetColor メッセージのみを受け取るということがもはや保証されなくなりました。ユーザが
option キーを押しながら (スポイトツールを起動するために) クリックを行うとき、Color
Picker Manager は現在のカラーピッカーがそのクリックを処理するのを抑制し、その代わりに現在のカラーピッカーに
PickerSetColor メッセージを送ります。カラーピッカーはユーザカラーフラグをセットしてそのメッセージを送り、そのためオリジナルの色は決して変更されません。2.1
savvy のカラーピッカーの場合、風変わりな PickerSetColor メッセージを処理して、渡された新しい色を処理できなければなりません。この中には、ピッカーの右上隅にあるユーザカラーボックスを更新して新しい色を表示することや、カラーピッカーに含まれるスライダやテキスト編集フィールドを更新することなどが含まれます。試してみればわかりますが、Apple
のカラーピッカーはすべてこのように正しく動作します。
処理の手順と注意事項
1. Color Picker Manager はカーソルを変更する場合があります (スポイトカーソルに)。これを元に戻すのはピッカーの責任です。カラーピッカーが
null イベントの間にカーソルの更新を処理している場合、それ以上の処理を行う必要はありません。カーソルの更新をまったく行わないピッカーがあるとすると、ユーザが
option キーから指を離しても、このピッカーはスポイトのカーソルを表示し続けます。きちんと書かれたカラーピッカーは常にカーソルの更新を処理します。たとえば、ユーザがカーソルをテキスト編集フィールドの上に移動するとき、カーソルは
I ビームに変化することになります。
2. カラーピッカーは null イベントの間にカーソルの更新を処理している必要があるため、option
キーが押されている間、すべての null イベントは中断されます。そうでない場合、ある種の綱引きが
Color Picker Manager と個別のカラーピッカーとの間で始まり、ピッカーがカーソルを矢印またはその他の形に設定しようとするとき、Color
Picker Manager ではそれをスポイトに設定しようとして戦うことになります。
3. 最後に、Color Picker はムーバブルモーダル (PickColor() のようなよりミッドレベルの
API 呼び出しを使って) および標準モーダル (GetColor() のようなよりハイレベルの
API 呼び出しを使って) に呼び出すことができることも思い出してください。これら 2 つのケースに対して興味深い副作用が存在します。ピッカーがムーバブルモーダルに呼び出されるとき、(今すぐ考えてみてください)
ピッカーが表示されている間、option-クリックによりデスクトップにはどのような効果が現れるでしょうか。Event
Manager は option-クリックをかぎつけ、その代わりに現在のアプリケーションをユーザから取り上げ、現在のアプリケーションを隠し、Finder
に切り替えます。事実、他のプロセスのウィンドウに対しても option-クリックはよく似た動作を引き起こします。このような
"使用感" を改めるのではなく、Apple ではむしろこれを残すようにしました。このため、ユーザがスポイトカーソルを目にするのは、1)
option キーを押し続け、2) カーソルが現在のプロセスのウインドウのいずれかの上にあるときだけです。全体として、これはデベロッパが望む結果といえます。ペイントプログラムを開発していて、ユーザがその書類から
Color Picker を使って色をピックアップできるようにしたい場合、この書類ウインドウは当然のことながらアプリケーションによって所有されるウインドウです。また、Color
Picker がムーバブルモーダルに呼び出された場合、ユーザは当然のことながら Color Picker
のダイアログを画面上で移動して、書類の中で使用されている目的の色を取得できるようになるはずです。
厳密にモーダルなケースではまったく別の状況になります。それは非ムーバブルモーダルダイアログであるため、コンテキストを切り替える動作はまったく保持されません。事実、モーダルダイアログが表示されているときにデスクトップのクリックからユーザが期待できるものといえば、SysBeep()
サウンドだけです ("それをやっちゃあだめ" を意味する)。Color Picker 2.1
では、option キーが押されているときを除き、このような SysBeep() シナリオが保持されています。option
キーを押しているとき、ユーザはどこでもクリックでき (メニューバー以外)、デスクトップまたは他のプロセスのウインドウからでも色をピックアップできます。もちろんデメリットはダイアログを移動できないということです。このため、ユーザがピックアップしたい色が
Color Picker のダイアログの下にある場合が最悪です。
ところで Color Picker は、ヒットテスト領域を構築することによってすべてのヒットテスティングを処理します。その結果、カーソルがこの領域内にあり、option
キーを押しているとき、スポイトが取得されます。そうでない場合は取得できません。ムーバブルモーダルなケースでは、ウインドウ領域を蓄積した現在のレイヤウインドウのリストを見て回ります。一方、厳密にモーダルなケースでは
GetGrayRgn() を使用します。
最後に、ピッカーに渡された null イベントの間にカーソルを更新することを確認してください。また、いつでも
PickerSetColor メッセージを処理できるようにしてください。そうすれば、スポイトツールはすべてのカラーピッカーで自由に動作し、開発の過程で追加の作業を行う必要もありません
(大部分のサードパーティのカラーピッカーは修正を加えることなく完璧に動作します)。
新しい Component
Manager のメッセージ
新しいヘッダファイルをダウンロードするには、ここをクリックしてください。
Color Picker コンポーネントを書こうとしている場合、あるいはこれまでに書いた Color
Picker コンポーネントを改訂しようとしている場合にインプリメントを検討する価値のある、いくつかの新しい
Color Picker メッセージが追加されています。
PickerSetColorChangedProc
pascal ComponentResult PickerSetColorChangedProc(long storage, ColorChangedUPP colorProc,
long colorProcData) |
このメッセージは、初期化するために呼び出された後でピッカーに 1 度送られます。このメッセージには、呼び出し側アプリケーションの
colorChangedProc への procPtr が含まれています。このメッセージを使用すると、ピッカーではアプリケーションの
colorChangedProc を直接呼び出せるようになります。これは、ピッカーがすべてのイベントをスティールしているときには役立つことがわかっています。たとえば、ユーザがマウスボタンを押し続けながらスライダをドラッグしているときなどです。ユーザがマウスボタンを離すとき、制御は
Color Picker Manager に戻り、その時点で colorChangedProc が呼び出されます。しかし、ピッカーによっては、ユーザが
"ライブドラッグ" を行っている間に自分自身で colorChangedProc
を呼び出す必要がある場合もあります。
ただし、継続的に colorChangedProc を呼び出すと、colorChangedProc
がどの程度プロセッサの負担になるかにより、処理速度が低下することがあります。このため、新しい
Color Picker では、アプリケーションを呼び出すことによって渡されるフラグフィールドに新しいフラグ
(kColorPickerCallColorProcLive) を定義しています。Color Picker Manager
がピッカーに PickerInit メッセージを送るとき、ピッカーにはこのフラグのコピーが渡されます。このため、PickerSetColorChangedProc
をサポートする場合には、次の処理を行うことをお勧めします。
1) Color Picker Manager が colorChangedProc を呼び出すためのプロセッサ時間を取得できないときは、マウスドラッグの間だけこれを呼び出します。
2) kColorPickerCallColorProcLive フラグがセットされている場合だけこれを呼び出します。
NPickerGetColor、
NPickerSetColor、
NPickerGetProfile、
NPickerSetProfile、
および 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)
これらのメッセージは、オリジナルの Color Picker 2.0 メッセージと単純に平行しています。ただし、オリジナルの
Color Picker 2.0 がシステム特性ハンドルを渡すのに対して、これらのメッセージはシステム特性参照を渡します。これは
ColorSync 2.x のサポートを反映した結果です。2.0 メッセージの詳細については、『Advanced
Color Imaging Reference』を参照してください。
Color Picker
Component Manager メッセージの注意事項
コンポーネントは 1 つの "メイン" エントリポイントだけを持ち、Component
Manager はこのエントリポイント経由でコンポーネントにメッセージを送ることを思い出してください。通常、"メイン"
関数の中には重要な case ステートメントのようなものを置きます。メッセージに基づいて、関数を呼び出したり、認識できない値を受け取った場合は
paramErr を返したりします。
新しい Color Picker メッセージをすべてインプリメントするわけではない場合、サポートしないすべてのメッセージに対して
paramErr を返す必要があります。これにより、Color Picker Manager ではいくつかの他の方法でメッセージを処理することができます。
また、標準 Component Manager メッセージ kComponentCanDoSelect が存在することにも注意してください。これは、Color
Picker Manager に "はい、このメッセージを処理する方法を知っています" あるいは
"いいえ、処理できません" ということを応答するために最もふさわしい場所でもあります。Color
Picker がアプリケーションを避けて動作しようとしないように、この処理を行うことは重要です。
参考文献
|