OscillatorViewの実装【実践的Macintoshプログラミング解説】

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

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

LinkIconホーム

更新日 2009-05-24

ビューを作る

OscillatorViewの実装

oscillatorView.png モデルが完成したので、次にビューを作成します。OscillatorViewはNSBezierPathとバインドさせて、そのパスを表示する様に設計します。

 完成したビューは右図のような外観を持つ至ってシンプルなものです。

データパスと表示パス

 OscillatorViewはNSBezierPathを表示するビューですが、表示すべきパスを何の加工もせずそのまま表示できるわけではありません。ビューの大きさに合わせる必要があります。したがって二つのパスを持つ必要があります。 

 ここでは表示すべき元データに相当するパスをデータパス、ビューの大きさに合わせた表示用のパスを表示パスと呼ぶ事にします。

データパスのバインディングに必要なもの

 データパスはコントローラ経由でOscillatorCDクラスのwaveformにバインドします。そのために必要なのは、

  1. コントローラのアウトレット
  2. データパスのインスタンス変数
  3. データパスのアクセサメソッド

の三つです。

OscillatorViewのインターフェイスファイル

 上で述べた三つと表示パスのインスタンス変数をインターフェイスファイルに記述します。

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

#import <Cocoa/Cocoa.h>


@interface OscillatorView : NSView
{
    IBOutlet    NSArrayController   *controller;

    NSBezierPath    *dataPath, *displayPath;
}

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

@end

生成と廃棄

 イニシャライザでは、

  1. スーパークラスのイニシャライザを呼び出す
  2. インスタンス変数を初期化する
  3. 通知を受け取るための登録を行なう

という三つの事を行なっています。
 ここで受け取りの設定をしている通知はNSViewFrameDidChangeNotificationですから、ビューのサイズが変化した時に通知を受け取る事ができます。object:に自分自身を設定しているので、自分が発行した通知すなわち自分のサイズが変化したときの通知だけを受け取る事ができます。

 deallocメソッドではデータパスと表示パスをそれぞれreleaseして、通知の受け取りを解除しています。

 バインディングの設定はアウトレットが有効になったawakeFromNibメソッドで行ないます。データパスをNSArrayControllerで現在選択されている(selection)オブジェクトのwaveformとバインドします。

//
//  OscillatorView.m
//

#pragma mark -
#pragma mark Initializer and Deallocator

- (id)initWithFrame:(NSRect)frame
{
    NSNotificationCenter    *nc = [NSNotificationCenter defaultCenter];

    self = [super initWithFrame:frame];
    if(self)
    {
        dataPath = displayPath = nil;
        [nc addObserver:self
               selector:@selector(frameDidChange:)
                   name:NSViewFrameDidChangeNotification
                 object:self];
    }
    return self;
}

- (void)dealloc
{
    [dataPath release];
    [displayPath release];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
}

- (void)awakeFromNib
{
    [self bind:@"dataPath"
      toObject:controller
   withKeyPath:@"selection.waveform"
       options:nil];
}

アクセサメソッド

 アクセサメソッドはオブジェクトをセットする場合の定石通りの処理なので、説明は省略します。
 データパスが変更された時はそれに対応する表示パスも更新する必要があるので、updateDisplayPathメソッドを呼び出しています。

//
//  OscillatorView.m
//

#pragma mark -
#pragma mark Accessor Methods

- (NSBezierPath *)dataPath  {return  dataPath;}
- (void)setDataPath:(NSBezierPath *)newPath
{
    [newPath retain];
    [dataPath release];
    dataPath = newPath;

    [self updateDisplayPath];
}