Geometry 関数
NSBundle
NSDictionary
NSFileManager
NSMutableAttributedString
NSNumber
NSScanner
NSString
NSTimer
Graphic 関数
NSApplication
NSBezierPath
NSCell
NSColor
NSCursor
NSCustomImageRep
NSDocument
NSDocumentController
NSDragging
NSEvent
NSFontManager
NSGraphicsContext
NSImage
NSMenu
NSOutlineView
NSPanel
NSPopUpButton
-ポップアップの枠を消す
-Cocoa バインディングでエンコーディングメニューを作る
NSResponder
NSScrollView
NSString 追加
NSTableColumn
NSTableView
NSTextStorage
NSTextView
NSToolbar
NSView
NSWindow
NSWorkspace
その他
.nib ウィンドウ
Views パレット
クラス
インスタンス変数
メソッド
CFXML
Carbon Event
Carbon Graphics
Cocoa で日本語
メソッド
その他

- 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



[Home] [Download] [Archives] [BBS] [Cocoa Programming Tips 1001] [Core Foundation の秘密] [Safari Developer Center] [はじめてのブラウザのつくり方] [Sketch BP] [スクリーンセイバーを作ろう] [Objective-C 最適化] [Authorization API 完全理解] [Mac OS X Programming Books Review] [オブジェクト指向の言語比較論] [panther-dev]

mailto: mkino@xd5.so-net.ne.jp