オフスクリーンビューの実装
次にプレビュー、サムネイルの両方で使っているオフスクリーンビューについて説明します。このビューの機能はセットされたRepeatingMotifオブジェクト(繰返し紋様を描くためのパラメータを保持するオブジェクト)を使って自分自身に描画する事です。
インターフェイスファイル
オフスクリーンビューの名前はRepeatingMotifViewとし、NSViewを継承させます。
NSViewを継承しているので、dataWithPDFInsideRect:メッセージを送ってPDFデータを生成させる事ができますし、displayRectIgnoringOpacity:inContext:でグラフィックコンテキストに描画させる事ができます。
セットされたRepeatingMotifオブジェクトを入れておく変数を宣言します。またRepeatingMotifオブジェクトをセットするアクセサメソッドは外部から呼び出されるので、ここに宣言しておきます。
#import <Cocoa/Cocoa.h>
@class RepeatingMotif;
@interface RepeatingMotifView : NSView
{
RepeatingMotif *repeatingMotif;
}
- (void)setRepeatingMotif:(RepeatingMotif *)rm;
@end
初期化と廃棄
ここからはインプリメンテーションファイルのコードになります。
初期化メソッドでは変数repeatingMotifをnilに初期化しておきます。
deallocメソッドではrepeatingMotifにreleaseメッセージを送ってから親クラスのdeallocメソッドを呼び出します。nilにメッセージを投げても問題ないので、nilかどうかのチェックは行ないません。
これはオブジェクトを保持する場合の定型の処理です。
#import "RepeatingMotifView.h"
#import "RepeatingMotif.h"
#import "RepeatingMotifGeneratorCG.h"
@implementation RepeatingMotifView
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
repeatingMotif = nil;
}
return self;
}
- (void)dealloc
{
[repeatingMotif release];
[super dealloc];
}
オブジェクトをセットするアクセサメソッド
オブジェクトをセットするアクセサメソッドを実装します。これも定型の処理です。Objective-C 2.0だとこういったものも簡略化されるのでしょうが、このクラスはMac OS X 10.3.9でも動くアプリケーションから持ってきたので、自前で実装しています。
- (void)setRepeatingMotif:(RepeatingMotif *)rm
{
[rm retain];
[repeatingMotif release];
repeatingMotif = rm;
}
描画のコード
このクラスで最も肝心な描画のコードですが、実際の描画はRepeatingMotifGeneratorCGオブジェクトにお任せなので、ここではそのメソッドを呼びだして終わりです。
- (void)drawRect:(NSRect)rect
{
[[RepeatingMotifGeneratorCG sharedGenerator] drawToView:self
repeatingMotif:repeatingMotif];
}
描画のコードはビューに持たせるべきなのか?(継承か使用か)
独自の描画コードはビューのサブクラスに持たせるべきなのでしょうか?それともビューから分離すべきなのでしょうか?どちらが正解なのかはわかりませんが、私は過去の経緯もあって繰返し紋様を描画するコードはビューではなくモデルオブジェクトに持たせています。
そのそも最初はビューではなくNSImageのサブクラスを作って、そこに描画コードを実装していました。これだとそのクラスのインスタンスを多数生成した時にメモリの無駄遣いではないかと思って描画コードを独立させたわけです。(本当に同一クラスのメソッドがメモリ上に重複して存在するのかどうかは知りません。そんな無駄な事はしないような気もする・・・)
独立させた事はビットマップデータだけではなくベクトルデータを扱う様に拡張する際にメリットとなりました。NSImageのサブクラスで描画していた時は自分自身に描いていたためビットマップデータだけしか扱えなかったのですが、描画コードを独立させてNSViewのdrawRect:から呼び出す事でベクトルデータを扱える様に拡張できたわけです。
フレームワークが提供するクラスのサブクラスはやたらと作らないほうがいいような気もします。(でもNSDocumentのようにサブクラス化される事が前提のクラスもありますが)

HOME
前のページへ