BathyScaphe ネタ(その16)

やはり必要でしょう、フォーカスリングが

イメージ・ビューでも delete キーを叩きたい、という話があったのも、はや二週間以上前。他のところに手間取り、昨日からようやくプレビュープラグインに手を出し始めたところだ。
イメージ・ビューでショートカットでの操作を受け付けるということは、まず NSImageView が First Responder にならねばならぬ。サブクラスで -acceptsFirstResponder を上書きして、YES を返してやればいい。ついでに -needsPanelToBecomeKey も YES を返すようにしてやった。
早速試してみると、ちゃんと first responder にはなってくれるのだが、視覚的に判別ができないことに気付いた。…そう、フォーカスリングが表示されないのだ。これでは「今、キーを叩くと誰が反応するのか?」がわかりにくい。こういうマズそうな問題は絶対に潰しておかないといけないんだゾ!*1

自力で描けと仰るのですね、フォーカスリングを

そこで早速 NSImageView にフォーカスリングを付けようと思ったら、なんだか意外にうまくいかない。-setFocusRingType: や -focusRingType で NSFocusRingTypeExterior をセットしてやっても、一切描いてくれないのだ。まぁ、普通 NSImageView にフォーカスリングを付ける用途がないからね。だから必要なときは自分で描きなさい、ということらしい。
……どうやって描くの?

失敗を経て、いざ成功してみると、フォーカスリングって

Carbon の世界に踏み込みたくはないから、AppKit 内を探して NSSetFocusRingStyle() なる関数を見つけてきた。これを呼ぶとフォーカスリングが描けるらしい。しかしこれをどこで呼べばいいのかがよくわからん。試しに -drawRect: を上書きして、

- (void) drawRect: (NSRect) aRect
{
	NSSetFocusRingStyle(NSFocusRingAbove);
	[super drawRect: aRect];
}

みたいにしてみたら、下図のようになった。明らかに失敗だ。


しばらく弄り回しても見当がつかないので、Google で探してみたら、やはり似たようなことをやっている人が居るもので、ほどなく解答が見つかった。大ざっぱには次のようにするといいようだ:

- (void) drawRect: (NSRect) aRect
{
	[super drawRect: aRect]; // これを先に

	NSSetFocusRingStyle(NSFocusRingNone);
	NSRectFill(aRect); // ほほぅ…なるほどね
}


しかし、いざフォーカスリングを付けてみると、確かに判別は付きやすいが、意外と目障りがられて逆に不評を買うかもしれないと気になりだしている。実際の使用環境上、ここにフォーカスが当たっている時間が長いことが想定されるからね。まだしばらく時間はあるから、もう少し考えてみよう。

*1:ちくしょう、明日のおとぎ銃士赤ずきんも見られないんだよな…