BezierPathViewを改良する【実践的Macintoshプログラミング解説】

印刷用表示 |テキストサイズ 小 |中 |大 |

CoreData版 Repeating Motif Generator の開発 Repeating Motif Wonderland CoreData 実践的 Macintosh プログラミング解説

LinkIconホーム

更新日 2009-05-24

リサージュ図形が複数選択された時に、表示が適切になる様にする

BezierPathViewを改良する

multipleSelection.png
 旧バージョンでは複数選択を許していなかったのですが、カット&ペーストができる様になった状況で考えてみると、やはり幾つかのリサージュ図形をまとめてカットできた方が便利です。

 複数選択自体はテーブルビューの設定を変えるだけで簡単にできるのですが、見た目で気になる部分が出てきました。右の図の様にOscillatorViewとLissajousViewに何も表示されなくなってしまうのです。

 そこで複数のオブジェクトが選択されている時はメッセージを表示する様にBezierPathViewを改良する事にしました。

テーブルビューの設定を変更する

 複数のオブジェクトを選択できる様にする事は簡単です。Interface Builderでテーブルビューの設定を変えるだけです。

 下の図はテーブルビューを選択した時のInterface Builderのインスペクタですが、SelectionのMultipleにチェックを入れればOKです。

multipleSelection.png

 元々カット&ペーストのコードは複数のオブジェクトが選択されている事を前提にしているので、特に問題は発生しません。問題はOscillatorViewとLissajousViewの表示です。

複数選択状態を表すフラグを追加する

 これはOscillatorViewとLissajousViewで共通の問題ですから、両者のスーパークラスであるBezierPathViewを改良するのが適切です。

 複数選択の時に表示を変えるわけですから、表示に関わるメソッドで複数選択の状態であるかどうかがわからないといけません。そこで、複数選択状態を表すフラグをインスタンス変数として追加します。

//
//  BezierPathView.h
//  RepeatingMotifGenerator
//
//  Copyright NovemberKou 2008. All rights reserved.
//

#import <Cocoa/Cocoa.h>


@interface BezierPathView : NSView
{
    IBOutlet    NSArrayController   *controller;

    BOOL            isXView, multipleSelection;
    NSBezierPath    *dataPath, *displayPath;
}

- (NSBezierPath *)dataPath;
- (void)setDataPath:(NSBezierPath *)newPath;

@end

複数選択フラグを更新する

 このフラグを更新するのは選択状態が変わる時ですから、データパスのSetterが適切です。

//
//  BezierPathView.m
//

- (void)setDataPath:(NSBezierPath *)newPath
{
    multipleSelection = [[controller selectedObjects] count] > 1;

    [newPath retain];
    [dataPath release];
    dataPath = newPath;

    [self updateDisplayPath];
}

フラグによって表示内容を切替える

 フラグが立っていたら複数のオブジェクトが選択されているというメッセージを表示し、そうでなければ従来通りベジエパスを表示します。よってdrawRect:メソッドを以下の様に変更します。

 ここまでは特に難しい事はありません。

//
//  BezierPathView.m
//

- (void)drawRect:(NSRect)rect
{
    [[NSBezierPath bezierPathWithRect:[self bounds]] stroke]; 

    if(![self inLiveResize])
        if(multipleSelection)
            [self showMultipleSelectionMessage];
        else
            [displayPath stroke];
}

メッセージを表示する

 ビューに文字列を表示するにはNSStringのdrawAtPoint:withAttributes:メソッドを使います。ビューにフォーカスがあたっている時に使う様に、という注意書きがありますがdrawRect:から呼び出しているメソッドで実行するわけですから問題ありません。

//
//  BezierPathView.m
//

- (void)showMultipleSelectionMessage
{
    NSString    *message = NSLocalizedString(@"multipleSelection",nil);

    [message drawAtPoint:NSMakePoint(0,0) withAttributes:nil];
}

 NSLocalizedString()を使いましたので、Localizable.stringsにキー値ペアを追加します。

"setAmplitude" = "Change Amplitude";
"setFrequency" = "Change Frequency";
"setPhaseLag" = "Change PhaseLag";
"setResolution" = "Change Resolution";

"cutLissajous" = "Cut Lissajous Figure";
"deleteLissajous" = "Delete Lissajous Figure";
"pasteLissajous" = "Paste Lissajous Figure";

"multipleSelection" = "Multiple Selection";

multipleSelection2.png
 さて、これで実行してみると右の図の様になります。

 … 機能としては満足しているものの、これではあまりに見栄えが悪いですね。

 次のページでは文字列のサイズや位置を変更して、もう少し見た目を改善します。