LoginSignup
4

More than 5 years have passed since last update.

キーウィンドウが移動しないパネルを作る (NSFontPanelみたいな)

Posted at

目的

タイトルが長いけど、NSFontPanel (もしくは NSColorPanel)みたいな挙動をする NSPanelを作りたい。

メモ.appなんかでフォントパネルを操作してみると以下のような動きをする。

  • アクティブなのは常にメインウィンドウ (タイトルバーの文字がグレーアウトしていない)
  • パネルの上をクリックしてもパネルがアクティブにならない
  • パネルのタイトルバーをクリックするとパネルがアクティブになる
  • 非アクティブ状態でもパネル上のテーブルやボタンなどの部品は操作できる

フォント_と_メモ_—_フォントパネルの挙動.png

これをどう作るか、という話

方法

大げさに書いているが実際のところは簡単だった。

  • パネルのサブクラスを作る (MyPanelとか)
  • インターフェースビルダで配置したパネルの Custom Classを MyPanelにする
  • MyPanelの awakeFromNibの中などで setBecomesKeyOnlyIfNeeded: メソッドを呼ぶ
MyPanelで実装
-(void)awakeFromNib
{
    [self setBecomesKeyOnlyIfNeeded:YES];
}

これだけ。

http://cocoaapi.hatenablog.com/entry/00000226/recID37326 によれば

必要な時だけキーウインドウになるかを返します。
初期設定はNOを返します。

とのこと。

「アクティブなウィンドウ = キーウィンドウ」という理解でいいんだろうか。確かにキーイベントを受け取るのはアクティブなウィンドウだから合ってる気がする。

ソース

[TODO]

-

補足1

setBecomesKeyOnlyIfNeededは本来 NSViewの needsPanelToBecomeKeyメソッドと対で使うものらしい。

パネルがキーウインドウになるかを制御する
サブクラスでオーバーライドして使います。

「パネルの中にあるビューから要求を受けた時だけアクティブになる」ということ。今回は要求を出すビューがないからパネルがアクティブにならない。

フォントパネルの右上にあるフォントサイズ指定の NSTextFieldをクリックすると、パネルがアクティブになる。数値を入力するためにパネルがキーウィンドウになったということだが、おそらく NSTextFieldの needsPanelToBecomeKeyは YESを返すようになっているんだと推測できる。

補足2:カスタムビューをパネルに乗せるとき

この方法で独自のUI部品をパネルに載せて使いたいときは、NSViewの acceptsFirstMouseメソッドをオーバーライドする。これを使うことで、パネルのアクティブ化だけに使われていた最初のマウスイベントもビューに通知されるようになる。逆に、これを実装しとかないとUI部品に対するクリックイベントを拾ってもらえない。

-(BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
    return YES;
}

アクティブでない時、マトリックスをマウスダウンしたときに呼ばれます。
サブクラスでオーバーライドします。YESを返すと、アクティブでない時、マトリックスをクリックすると、アプリケーションはアクティブになりウインドウは前面にきて、マトリックスがクリックされメッセージを送信します。NOを返すとアプリケーションはアクティブになり、ウインドウは前面になりますが、マトリックスをクリックしません。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4