2011年4月26日火曜日

Cocoa Tabbed Interface tabのoverflow処理


Caccoで作図してみた。たしかに手軽でわかりやすいサイトだ。ま、絵心がないからどんなToolも猫に小判なんだけど。

それはともかく、TabbedInterfaceの続き。ウィンドウのサイズが変更されて、tabが表示しきれなくなった時の処理を書いている。

表示しきれなくなったら、tabの両端に「まだこっちにtabがあるよ」ボタンを表示する。

今現在はTabBarというNSViewのサブクラスで、単にボタンの画像を出力しているだけ。そのため、マウスカーソルがホバーした時やmouseDownが来た時の処理はいちいちTabBarクラスが担当している。例えばmouseDownは現在こうなっている。
-(void)mouseDown:(NSEvent *)theEvent{
    NSPoint point = [self convertPointFromBase:[theEvent locationInWindow]];
    if(leftOverflowButtonState!=OV_DISABLE){
        if (NSPointInRect(point, leftOverflowRect)){
            if(leftOverflowButtonState==OV_HOVER) leftOverflowButtonState=OV_PUSHED;
            [self setNeedsDisplay:YES];
        }
    }
    if(rightOverflowButtonState!=OV_DISABLE){
        if (NSPointInRect(point, rightOverflowRect)){
            if(rightOverflowButtonState==OV_HOVER) rightOverflowButtonState=OV_PUSHED;
            [self setNeedsDisplay:YES];
        }
    }
    
}

2つの画像についていちいち同じ処理をしている。馬鹿みたい。(^^;)これは書きなおさなければ、と思いつつ、とりあえずキリのいいところ書いてしまおうという素人技が炸裂中。

書き直しの方針として、Controllerを作ってTabBarとOverflowButtonを管理するようにしようと考えている。それが上のCaccoの図になっているわけですな。OverflowButtonもNSViewかNSButtonのサブクラスにしてしまえばきっと楽だろう。画面上に2つしか表示しないので、Viewにする贅沢をしてもいいはず。

さて、tabがoverflowしたら、表示しきれないtabを再表示するときはoverflowボタンを押すと望む方向にスクロールしていくのがいいだろう。

しかし、自分の好みとしては「アクティブなtabを隠さない」のがいいと思うので、こんな感じにしてみた。

tabは10個あって、現在表示しているのは先頭の5個。

右側のoverflowボタンを押すと右にスクロールしていく、わけだが、アクティブなtabが「1」なので、スクロールすると「1」が隠れてしまう。そのため、こういう場合はメニューで隠れているtabを表示するようにした。
この部分のソースはこうなっている。

-(void)tabScroll:(NSInteger)direction :(NSEvent*)theEvent{
    if (direction==OV_LEFT) {
        
        if (endIndex==activeTabIndex) {
            NSMenu* theMenu=[[[NSMenu alloc]initWithTitle:@"overflow_menu"]autorelease];
            NSMenuItem* item;
            for (NSInteger i=0; i0) {
            startIndex--;
            endIndex--;
            [self  setNeedsDisplay:YES];
        }
    }
    else{
        if (startIndex==activeTabIndex) {
            NSMenu* theMenu=[[[NSMenu alloc]initWithTitle:@"overflow_menu"]autorelease];
            NSMenuItem* item;
            for (NSInteger i=endIndex+1; i<[[self subviews]count]; i++) {
                Tab* tab=[[self subviews] objectAtIndex:i];
                item=[[NSMenuItem alloc]initWithTitle:[tab title] action:@selector(moveIndexByMenu:) keyEquivalent:@""];
                [item setTag:[tab index]];
                [theMenu addItem:item];
                [item release];
                
            }
            [NSMenu popUpContextMenu:theMenu withEvent:theEvent forView:self];
            
        }
        
        else if(endIndex<[[self subviews]count]){
            endIndex++;
            startIndex++;
            [self  setNeedsDisplay:YES];
        }
    }
}

で、メニューから「「10」を選ぶと、

「10」を一番右端にして表示しなおす、と。

左ボタンと右ボタンで同じコードを2回ずつ書いている、という状態の他は、ほぼ考えていた通りを動きをするようになってきた。

そろそろ、OutlineView、TableViewをあわせて、まともにフォルダの中身を表示できるのか確かめたくなってきた。

Tab関連のクラスの書き直しは今度の3連休に挑戦しよう。

0 件のコメント:

コメントを投稿