7

Apple のサンプル コードとドキュメントを読むと、たとえばXcode エディタ ウィンドウの「ジャンプ バーNSPathControl」と同様に動作するように を構成する方法がわかりません。

Xcode エディターのカスタム パス コントロール

つまり、パス(または他の種類の階層)を表し、パスの各コンポーネントをクリックして階層をナビゲートするポップアップにします..?

NSPathControlDelegateクリック音を聞いて一時的なウィンドウにメニューを表示することで、そのような動作を偽造する幸運に恵まれた人はいますか?

OSSの実装が期待される一般的な設計のようですが、そのような運はまだありません..

4

2 に答える 2

4

NSPathControl のサブクラスを作成して、mouseDown: を使用してコンポーネント セルのコンテキスト メニューを正しい位置にポップアップできるようにしました。必要に応じてより深いメニューを作成するために、メニューにデリゲートも追加しました。

- (void)mouseDown:(NSEvent *)event {

    NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];


    NSPathCell *cell = self.cell;
    NSPathComponentCell *componentCell = [cell pathComponentCellAtPoint:point
                                                              withFrame:self.bounds
                                                                 inView:self];

    NSRect componentRect = [cell rectOfPathComponentCell:componentCell
                                               withFrame:self.bounds
                                                  inView:self];

    NSMenu *menu = [componentCell menuForEvent:event
                                        inRect:componentRect
                                        ofView:self];

    if (menu.numberOfItems > 0) {
        NSUInteger selectedMenuItemIndex = 0;
        for (NSUInteger menuItemIndex = 0; menuItemIndex < menu.numberOfItems; menuItemIndex++) {
            if ([[menu itemAtIndex:menuItemIndex] state] == NSOnState) {
                selectedMenuItemIndex = menuItemIndex;
                break;
            }
        }

        NSMenuItem *selectedMenuItem = [menu itemAtIndex:selectedMenuItemIndex];
        [menu popUpMenuPositioningItem:selectedMenuItem
                            atLocation:NSMakePoint(NSMinX(componentRect) - 17, NSMinY(componentRect) + 2)
                                inView:self];
    }
}

- (NSMenu *)menuForEvent:(NSEvent *)event {
    if (event.type != NSLeftMouseDown) {
        return nil;
    }
    return [super menuForEvent:event];
}
于 2013-05-03T15:36:09.297 に答える
2

メニュー項目の遅延読み込みに対応するために、ステファンの回答を少し拡張しました。セルごとに事前にメニューを作成するのではなく、メニューを呼び出すための小さなプロトコルを作成しました。

NSPathControlExtended.h

@protocol NSPathControlExtendedDelegate <NSPathControlDelegate>

@required
- (NSMenu *)pathControl:(NSPathControl *)pathControl menuForCell:(NSPathComponentCell *)cell;

@end

@interface NSPathControlExtended : NSPathControl

@property (weak) id <NSPathControlExtendedDelegate> delegate;

@end

NSPathControlExtended.m

#import "NSPathControlExtended.h"

@implementation NSPathControlExtended

@synthesize delegate;

- (instancetype)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
    }
    return self;
}

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];

    // Drawing code here.
}

- (void)mouseDown:(NSEvent *)event {

    NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];


    NSPathCell *cell = self.cell;
    NSPathComponentCell *componentCell = [cell pathComponentCellAtPoint:point
                                                              withFrame:self.bounds
                                                                 inView:self];

    NSRect componentRect = [cell rectOfPathComponentCell:componentCell
                                               withFrame:self.bounds
                                                  inView:self];

    NSMenu *menu = [delegate pathControl:self menuForCell:componentCell];

    if (menu.numberOfItems > 0) {
        NSUInteger selectedMenuItemIndex = 0;
        for (NSUInteger menuItemIndex = 0; menuItemIndex < menu.numberOfItems; menuItemIndex++) {
            if ([[menu itemAtIndex:menuItemIndex] state] == NSOnState) {
                selectedMenuItemIndex = menuItemIndex;
                break;
            }
        }

        NSMenuItem *selectedMenuItem = [menu itemAtIndex:selectedMenuItemIndex];
        [menu popUpMenuPositioningItem:selectedMenuItem
                            atLocation:NSMakePoint(NSMinX(componentRect) - 17, NSMinY(componentRect) + 2)
                                inView:self];
    }
}

- (NSMenu *)menuForEvent:(NSEvent *)event {
    if (event.type != NSLeftMouseDown) {
        return nil;
    }
    return [super menuForEvent:event];
}

@end
于 2014-07-14T18:24:51.387 に答える