HMDT - Logic and Intuition -

about HMDT

Cocoa Programming Tips 1001

Application Kit

NSPopUpButton

Application Kit - NSPopUpButton

ポップアップの枠を消す

Keywords: setBordered

ポップアップメニューには、Aqua の枠が付いているけど、たまにそれがないやつがあるじゃない?下の図の右側のようなやつだ。

これを作るにはどうするか?setBordered: を使うんだ。

Application Kit/NSCell.h

- (void)setBordered:(BOOL)flag;

NSCell の API なんで注意。これを、NSPopUpButtonCell に対して呼んでやるんだ。

(sample)

    NSPopUpButton* popUp;
    [[popUp cell] setBordered:NO];

これで枠が消えるよ。

Application Kit - NSPopUpButton

Cocoa バインディングでエンコーディングメニューを作る

Keywords: Cocoa Bindings, _popUpItemAction:

Cocoa バインディングを利用して、エンコーディングを選択するためのポップアップメニューを作ってみよう。このポップアップメニューは、選択できるエンコーディングの一覧を表示するんだ。で、エンコーディングを選択すると、その値が Cocoa バインディングを利用して、他のオブジェクトに通知される。また、他のオブジェクトからのエンコーディングの変更通知を受け取ると、メニューの選択項目が変わるんだ。

こういうメニューを実装するには、2 つの機能が必要になる。1 つは、エンコーディングのメニューを作るもの。もう 1 つは、選択されたエンコーディングの値を保持するモデルクラスを提供することだ。今回は、この 2 つの機能を 1 つの Encoding というクラスで実装しよう。

Encoding クラスの説明の前に、ポップアップメニューをどうバインディングするのかを考えよう。ポップアップメニューである NSPopUpButton は、Interface Builder で調べてみると、選択された項目に対するバインディングは、selectedIndex、selectedObject、selectedTag、selectedValue といったものがあることが分かる。このメニューでは、ポップアップメニューで選択された項目である NSMenuItem と、エンコーディングを表す NSStringEncoding を関連づける必要がある。NSStringEncoding は、実際のところ unsigned 型なので、ここでは NSMenuItem のタグを使うことにしよう。だから、バインディングする項目は、selectedTag になる。

Encoding クラスは、unsigned 型の encodingValue というプロパティを提供することにしよう。そして、ポップアップメニューは、selectedTag を encodingValue にバインディングする。この設定は、次の図のようになるんだ。

次に、エンコーディングのメニューの作成を考えよう。これはバインディングを使うと、NSString でしか設定できなかったり何かと面倒くさいので、手で作ることにする。Encoding クラスには、ポップアップメニューへの参照を持たせる。そして、awakeFromNib メソッドの中で、メニューを作るんだ。たとえば、次のようにする。

EncodingsMenu/Encodings.m

// メニューに表示するエンコーディングです
static CFStringEncodings    _cfEncodings[] = {
    kCFStringEncodingShiftJIS,              // Japanese (Shift JIS)
    kCFStringEncodingISO_2022_JP,           // Japanese (ISO 2022-JP)
    kCFStringEncodingEUC_JP,                // Japanese (EUC)
    kCFStringEncodingShiftJIS_X0213_00,     // Japanese (Shift JIS X0213)
    kCFStringEncodingInvalidId, 
    kCFStringEncodingUTF8,                  // Unicode (UTF-8)
    kCFStringEncodingInvalidId, 
    kCFStringEncodingISOLatin1,             // Western (ISO Latin 1)
    kCFStringEncodingMacRoman,              // Western (Mac OS Roman)
};

@implementation Encodings

- (void)awakeFromNib
{
	// NSMenuのインスタンスを作ります
    NSMenu* encodingMenu;
    encodingMenu = [[[NSMenu alloc] 
            initWithTitle:@"encoding"] autorelease];
    
    int i;
    for (i = 0; i < sizeof(_cfEncodings) / sizeof(CFStringEncodings); i++) {
        id <NSMenuItem> menuItem;
        
        if (_cfEncodings[i] == kCFStringEncodingInvalidId) {
            // セパレータアイテムを作ります
			menuItem = [NSMenuItem separatorItem];
        }
        else {
            // CFStringEncodingをNSStringEncodingに変換します
            NSStringEncoding    encoding;
            encoding = CFStringConvertEncodingToNSStringEncoding(
                    _cfEncodings[i]);
            
            // エンコーディングの名前を取得します
            NSString*   encodingName;
            encodingName = [NSString 
                    localizedNameOfStringEncoding:encoding];
            
            // NSMenuItemのインスタンスを作ります
			// Actionには_popupItemAction:を指定します
            menuItem = [[[NSMenuItem alloc] 
                    initWithTitle:encodingName 
                    action:@selector(_popUpItemAction:) 
                    keyEquivalent:@""] autorelease];
            // タグとして、encodingを設定します
            [menuItem setTag:encoding];
        }
        
		// メニューにアイテムを追加します
        [encodingMenu addItem:menuItem];
    }
    
	// ポップアップメニューに設定します
    [popupButton setMenu:encodingMenu];
}

ここでは、表示するエンコーディングを、あらかじめ static の配列として定義しておく。そして、NSMenu のインスタンスを作り、NSMenuItem を追加していくんだ。NSMenuItem のインスタンスを作るときのポイントは、アクションに _popupItemAction: を設定することだ。これを設定すると、アクションが NSPopUpButtonCell に受け取られて、バインディングの処理が行われるようだ。

こうすると、エンコーディングメニューが実現できる。メニューを選択すると、バインディングを使って、モデルクラスである Encoding の encodingValue プロパティが設定される。

サンプルとして、encodingValue の値を、IANA 名に変換してテキストフィールドに設定するアプリケーションを作ってみた。この変換は、NSValueTransformer のサブクラスを作って実装してみた。メニューからエンコーディングを選択すると、その IANA 名がテキストフィールドに設定される。また、テキストフィールドに適切な IANA エンコーディング名を入れると、ポップアップメニューの選択が変更されるんだ。

ソースコードはこちらから。

■サンプルダウンロード:
EncodingsMenu.tar.gz

back to top content

Copyright © 2002-2006 HMDT. All rights reserved.