前回のコードの解説。
まず WebViewを載せる前面のウィンドウのクラスを定義する。WebWindowと名付けた。
WebWindow.h
@interface WebWindow : NSWindow {
}
@end
実装は初期化コードおよび key window になるための -[canBecomeKeyWindow] の実装。
WebWindow.m
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithContentRect:frame
styleMask:NSUtilityWindowMask
backing:NSBackingStoreBuffered
defer:NO];
if (self) {
[self setDisplaysWhenScreenProfileChanges:YES];
[self setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
}
return self;
}
- (BOOL)canBecomeKeyWindow
{
return YES;
}
Interface Builder ではベースとなる後ろのウィンドウだけを定義しておく。ここに戻るや進むのボタン、URLテキストフィールドなどを配置しておく。また WebWindowを配置するエリアを表すためにカスタムビューを配置しておく。あらかじめ Interface Builder で位置や大きさを設定しておくと、実行時に WebWindowの大きさや位置を簡単に決める事ができる。
WebViewは前面の WebWindowに載せるのでここには追加しない。ただアウトレットやアクションを Interface Builderで設定できると便利なのでインスタンス化だけしておく。
これらを使って必要な配線を済ませておく。
2つのウィンドウと WebView を統合する役割を担うのが WebController。ここで行う処理は:
・2つのウィンドウの結びつけ
・WebWindowへ WebViewを貼付ける
・NSProgressIndicatorの処理
NSProgressIndicatorは以前説明したので省略。
まずヘッダ。必要なインスタンス変数が定義されている。ほとんどがアウトレットで先ほどの InterfaceBuilderによる配線で準備される。
WebController.h
@class WebWindow;
@interface WebController : NSObject {
IBOutlet NSProgressIndicator* _progress_indicator;
IBOutlet WebView* _web_view;
IBOutlet NSWindow* _main_window;
IBOutlet NSView* _background_view;
WebWindow* _web_window;
}
@end
次に実装。Nib読み込み後に初期化する。
WebController.m
- (void)awakeFromNib
{
:
_web_window = [[WebWindow alloc] initWithFrame:[self webWindowFrame]];
[_web_window makeKeyAndOrderFront:nil];
[_web_window setContentView:_web_view];
[_main_window addChildWindow:_web_window ordered:NSWindowAbove];
:
}
まず WebWindowを生成する。続いて WebViewをコンテンツビューとして張りつける。
そして最後に -[NSWindow addChildWindow:ordered:] を使って2つのウィンドウを紐づける。紐付けによってベースのウィンドウの移動に合わせて WebWindowも位置関係を保ったまま移動するようになる。
WebWindowの位置と大きさは用意しておいたカスタムビューから取得する。
- (NSRect)webWindowFrame
{
NSRect frame = [_background_view frame];
frame.origin = [_main_window convertBaseToScreen:frame.origin];
return frame;
}
カスタムビューから得られる座標系は、そのビューが置かれているウィンドウ内のものになる。WebWindowはスクリーン座標系を使うので - [NSWindow convertBaseScreen:] で座標変換してやる。
最後にデリゲートを使ってベースのウィンドウのサイズが変わった時に WebWindowの大きさも変わる様にしておく。
// Main Window Delegate
- (void)windowDidResize:(NSNotification *)notification
{
[_web_window setFrame:[self webWindowFrame] display:YES];
}
これで2つのウィンドウがあたかも1つのウィンドウのように振る舞うようになる。
(おわり)