home link download back number special issue

HMDT - Special Issue / How to make a screen saver / ScreenSaver.framework APIs


+ ScreenSaver.framework の API

ここでは、ScreenSaver.framework の API を調べてみよう。ただし、ドキュメントが公開されているわけではないので(たぶん)、すべて想像と憶測と希望(!)がないまぜになっているものだ。そこんとこよろしく。

ScreenSaver.framework では 3 つのヘッダファイルが提供されている。

  • ScreenSaver.h
  • ScreenSaverView.h
  • ScreenSaverDefault.h

最初の ScreenSaver.h は、下の 2 つをまとめて import するためだけのヘッダだ。ScreenSaverView は、NSView を継承したクラスで、スクリーンセイバーの、挙動の中心となるクラスだ。ScreenSaverDefault は、NSUserDefault を継承していて、ユーザの初期設定を保存するために使うクラスだな。

- ScreenSaverView.h

ScreenSaverView は NSView を継承したクラスだ。その目的は、実際にスクリーンセイバーを描画する View を提供することだ。ScreenSaverView.h では、2 つのクラスメソッドと、12 のメソッド、あと 4 つのユーティリティ関数が提供されている。

[backingStoreType]

ScreenSaver/ScreenSaverView.h
+ (NSBackingStoreType)backingStoreType;

スクリーンセイバーを動かす際の NSBackingStoreType を取得する。調べるのはいいけど、どんな場面で使用するんだ?

[performGammaFade]

ScreenSaver/ScreenSaverView.h
+ (BOOL)performGammaFade;

想像だけど、セイバーの開始、終了時にフェードイン、アウトするかどうかを調べるメソッドだと思う。逆に、それを設定できるメソッドってないんだよね。

[initWithFrame]

ScreenSaver/ScreenSaverView.h
- (id)initWithFrame:(NSRect)frame;
- (id)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview;

初期化メソッドだ。モジュールで、初期化したい内容があるときは、これをオーバーライドするんだ。2 種類あって、前者の方は、普通の NSView の初期化と一緒。後者の方は、プレビュー用の初期化か、ほんちゃん用の初期化かが分かるようになってるんだ。プレビューのときに、違うことをやりたいときは、後者を使おう。

[animationTimeInterval, setAnimationTimeInterval]

ScreenSaver/ScreenSaverView.h
- (NSTimeInterval)animationTimeInterval;
- (void)setAnimationTimeInterval:(NSTimeInterval)timeInterval;

アニメーションの時間間隔を設定する。NSTimeInterval は double 型で、単位は秒だ。animationTimetInterval をオーバーライドして好きな値を返すことで設定できるんだ。

[startAnimation, stopAnimation, isAnimating]

ScreenSaver/ScreenSaverView.h
- (void)startAnimation;
- (void)stopAnimation;
- (BOOL)isAnimating;

最初の 2 つは、おもにユーザがオーバーライドして使うメソッドだ。startAnimation をオーバーライドすると、アニメーションが始まる前に呼び出される。stopAnimation はアニメーションがストップするときに呼び出されるわけだ。

isAnimating は現在アニメーション中かどうかを返してくれる。

[drawRect, animateOneFrame]

ScreenSaver/ScreenSaverView.h
- (void)drawRect:(NSRect)rect;
- (void)animateOneFrame;

これは描画系のメソッドだね。drawRect: は、おなじみの、NSView の実際の描画を行うメソッド。アニメーションを実装するには animateOneFrame をオーバーライドする。このメソッドは一定間隔でくり返し呼び出されるんだ。さらに、フォーカスの当たった状態になっている。

[hasConfigureSheet, configureSheet]

ScreenSaver/ScreenSaverView.h
- (BOOL)hasConfigureSheet;
- (NSWindow*)configureSheet;

設定シート関連のメソッドっす。hasConfigureSheet はユーザがオーバーライドして使うんだ。YES を返すようにすると、設定シートが使えるようになる。スクリーンセイバーパネルの“設定”ボタンが active になるんだ。デフォルトでは NO を返す。

設定ボタンを押すと、configureSheet が呼ばれて、NSWindow を要求される。ユーザはこれをオーバーライドして、適当なシートを作って返すようにしなきゃいけないんだ。普通は .nib をロードして返すわけね。

[isPreview]

ScreenSaver/ScreenSaverView.h
- (BOOL)isPreview;

これは、プレビュー中かどうか?を調べるメソッド。たとえば Randomizer モジュールとかは、プレビューとほんちゃんで、描画する内容が違うわけだ。プレビューのときは、Randomzier って表示するだけだからね。そんなとき、これが使える。

[SSRandomIntBetween, SSRandomFloatBetween]

ScreenSaver/ScreenSaverView.h
static __inline__ int SSRandomIntBetween(int a, int b)
{
    int range = b - a < 0 ? b - a - 1 : b - a + 1; 
    int value = range * ((float)random() / (float) LONG_MAX);
    return value == range ? a : a + value;
}

static __inline__ float SSRandomFloatBetween(float a, float b)
{
    return a + (b - a) * ((float)random() / (float) LONG_MAX);
}

ある範囲の乱数を発生させるユーティリティ関数。int 型を発生させる SSRandomIntBetween() と float を発生させる SSRandomFloatBetween() がある。たいしたことはやってないけど、せっかくあるんだから、便利に使わせてもらいましょう。

[SSRandomPointForSizeWithinRect]

ScreenSaver/ScreenSaverView.h
static __inline__ NSPoint SSRandomPointForSizeWithinRect(
        NSSize size, NSRect rect)
{
    return NSMakePoint(
        floor(SSRandomFloatBetween(
            rect.origin.x, rect.origin.x + rect.size.width - size.width)),
        floor(SSRandomFloatBetween(
            rect.origin.y, rect.origin.y + rect.size.height - size.height)));
}

ある NSRect があったとしようじゃないか。その中に、それより小さい NSRect をランダムに配置したいとしよう。ただし、はみ出ないですっぽり収まるようにね。そなんとき使えるのがこの関数だ。小さい NSRect のサイズと、大きい方の NSRect を渡してやれば、小さい NSRect の配置先が NSPoint の形で出てくる。

[SSCenteredRectInRect]

ScreenSaver/ScreenSaverView.h
static __inline__ NSRect SSCenteredRectInRect(
        NSRect innerRect, NSRect outerRect)
{
    innerRect.origin.x = 
        floor((outerRect.size.width - innerRect.size.width) / 2);
    innerRect.origin.y = 
        floor((outerRect.size.height - innerRect.size.height) / 2);
    return innerRect;
}

ある NSRect を、ある NSRect のまん中に配置するための関数だ。そんだけ。

- ScreenSaverDefaults.h

ScreenSaverDefaults は NSUserDefaults を継承したクラスだ。これを使えば、セイバーモジュールの固有の情報を保存しておけるわけだ。このクラスでは、クラスメソッドが 1 個提供されてる。

[defaultsForModuleWithName]

ScreenSaver/ScreenSaverDefaults.h
+ (id)defaultsForModuleWithName:(NSString*)moduleName;

モジュールの名前を指定して、NSUserDefault を取得するためのメソッドだ。これを使って NSUserDefault を取って、情報を保存するのに使えばいい。


Home | Link | Download | Back Number | Speciall Issue

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

HMDT