タイトル鶴薗賢吾のCocoaはやっぱり!出張版》#3-ウィンドウの形状変更と透明化(3)カテゴリーCocoa, 鶴薗賢吾のCocoaはやっぱり!出張版
作成日2001/9/12 14:22:11作成者新居雅行
■ ウィンドウ内の描画の手順
ウィンドウの中への描画については、CustomViewクラスのdrawRect :メソッドで行います。ウィンドウ内の描画と今まで書いてきましたが、実際には、ウィンドウ上に配置されているビューへ描けばよいのです。まずは、このCustomViewの初期化のところから見ていきます。初期化コードはawakeFromNibに書きます。awakeFromNibについては前回説明しましたので、詳しくは前回の記事を見てください。アプリケーション起動時にMainMenu.nibが読み込まれますが、その後にnibファイル内のインスタンスのawakeFromNibが呼ばれます。

// ソースファイル:CustomView.m
// メソッド:awakeFromNib :

circleImage = [ NSImage imageNamed : @"circle" ]; // 円の画像
pentaImage = [ NSImage imageNamed : @"pentagram" ]; // 五角形の画像
[ self setNeedsDisplay : YES ]; // 描画要求

ここで、ウィンドウの中に表示する画像を2つ読み込んでいます。imageNamed : というメソッドは、プロジェクトのResourcesに登録されている画像を読み込んでNSImageを作成するものです。最後に、
setNeedsDisplay : で自分自身に描画要求を行っていますが、これで、自分自身のdrawRect : が呼ばれて描画が行われることになります。その描画メソッドであるdrawRect : は以下のようになります。

// ソースファイル:CustomView.m
// メソッド:drawRect :

- (void) drawRect : (NSRect) rect
{
: 略
if ( [ [ self window ] alphaValue ] > 0.7 ) // ウィンドウの透明度で振り分け
[ circleImage compositeToPoint : NSZeroPoint
operation : NSCompositeSourceOver ]; // 円を描画
else
[ pentaImage compositeToPoint : NSZeroPoint
operation : NSCompositeSourceOver ]; // 五角形を描画

[ [ self window ] setHasShadow : NO ]; // ウィンドウの影の再計算のため
[ [ self window ] setHasShadow : YES ];
}

最初にウィンドウの透明度によって円を描くのか、五角形を描くのかを振り分けています。後で出てきますが、スライダーを動かすとウィンドウの透明度が変わるようになっています。ウィンドウの透明度を取得するのがalphaValueです。それから、「 self window 」と書いてありますが、windowメソッドで、このCustomViewが配置されている親のウィンドウを取得できるのです。

if ( [ [ self window ] alphaValue ] > 0.7 ) // ウィンドウの透明度で振り分け

 ★ NSWindow : ウィンドウの透明度を取得
  [書式] - (float) alphaValue
  [出力] 返り値 : 透明度 (不透明 0.0 〜 1.0 透明 )

さて、描画に戻ります。画像 ( NSImage ) の描画には、compositeToPoint : operation : を使っています。このメソッドは、描画の場所と背景との画像の演算の種類を指定できます。NSZeroPointは、原点( 0, 0 )を表します。NSCompositeSourceOverは、描画先との演算指定ではもっともよく使用されるもので「 不透明の部分は上書きして、透明部分は何もしない 」という演算です。

[ circleImage compositeToPoint : NSZeroPoint
operation : NSCompositeSourceOver ]; // 円を描画

 ★ NSImage : 指定位置に指定透明度、指定合成方法で画像を表示
  [書式] - (void) compositeToPoint : (NSPoint) point
       operation : (NSCompositingOperation) op
  [入力] point : 表示位置、op : 合成方法

最後に、ウィンドウの影のありなしを切り替えています。

[ [ self window ] setHasShadow : NO ]; // ウィンドウの影の再計算のため
[ [ self window ] setHasShadow : YES ];

意味のないことをしているようですが、透明なウィンドウでは、ウィンドウの中に描画を行うと、ウィンドウの形が変わり、それに連動してウィンドウの影の形も変わらなければなりません。しかし、ウィンドウの影の形は自動的には更新されません。更新させるために、ウィンドウの影をオフ/オンを行っています。この処理をしないと、以下のように直前の影が残った状態になってしまいます。

 

■ ウィンドウの透明度変更
次は、スライダーの処理を見てみましょう。Controller.mを見てください。

// ソースファイル:Controller.m
// メソッド:changeTransparency :

- (IBAction) changeTransparency : (id) sender
{
[ itsWindow setAlphaValue : [ sender floatValue ] ]; // 透明度変更
[ itsWindow display ]; // 再描画
}

先程のdrawRect : の中で、ウィンドウの透明度を参照していましたが、設定をしているのはここです。setAlphaValue : で透明度を変えることが出来ます。そして、displayメソッドで、ウィンドウを再描画させています。つまり、そのウィンドウの中にある、CustomViewも再描画されますので、先程のdrawRect : も呼ばれることになります。

 ★ NSWindow : ウィンドウの透明度を設定
  [書式] - (void) setAlphaValue : (float) windowAlpha
  [入力] windowAlpha : 透明度 (不透明 0.0 〜 1.0 透明 )

これを使うと、ウィンドウを画面に表示させる時にフェードインさせたり、ウィンドウを閉じる時にフェードアウトさせるような遊びをすることも可能になります。

[鶴薗賢吾]
関連リンクCocoaはやっぱり!