2

何千もの NSBezierPath を描画する NSView があります。mousemoved イベントで選択したものを強調表示 (塗りつぶしの色を変更) したいと思います。現時点では、mouseMoved 関数で次のコマンドを使用します。

     [self setsetNeedsDisplay:YES];

すべてのパスを再描画するために drawRect の呼び出しを強制します。選択したものだけを再描画したい。drawRect 関数で addClip を使用しようとしました:

      NSBezierPath * path = ... //builds the path here
      [path addClip];
      [path fill];

しかし、 drawRect は以前に描画された他のすべてのパスを破棄し、クリップされたパスのみを再描画するようです。

drawRectを呼び出すときにすべてのビューを無効にすることはできませんか? 以前のビューにあったものを段階的に上書きするだけですか?

ありがとう、ルカ

4

2 に答える 2

4

を使用する必要があります[self setNeedsDisplayInRect:…]。無効にするNSRectを渡すと、それがdrawRect:コールに渡される領域になります。

内部drawRect:で、渡された領域を確認し、その長方形の内部で必要な描画のみを実行します。

また、NSTrackingArea代わりにを使用することを検討mouseMoved:することもできます。これらを使用すると、特定の長方形を設定して、の更新をトリガーできます。

于 2009-12-23T13:41:54.060 に答える
1

四角形にどのパスが存在するかアプリオリにわからないので、すべてのパスのループを避けたいので、より速い方法で解決したと思います。幸い、私のパスは頻繁に変更されるわけではないので、すべてのパスを NSImage にキャッシュできます。私が設定したmouseMovedイベントで:

RefreshAfterMouseMoved = YES;

そして drawRect 関数に次のようなものを入れます:

if (RefreshAfterMouseMoved) {       
    [cacheImage drawAtPoint:zero fromRect:viewRect operation:1 
                       fraction:(CGFloat)1.0];
        //redraw only the hilighted path
}
else{
    if (cacheImage) [cacheImage release];   
    cacheImage = [[NSImage alloc] initWithSize: [self bounds].size ];
    [cacheImage lockFocus];
    // draw everything here
    [cacheImage unlockFocus];
    [cacheImage drawAtPoint:zero fromRect:viewRect operation:1 
                   fraction:(CGFloat)1.0];
}

このメソッドは、上記の setNeedsDisplayInRect メソッドと組み合わせて、mousedMoved 関数を追加できます。

   NSRect a, b, ab;
   a = [oldpath bounds];
   b = [newpath bounds];
   ab = NSUnionRect(a,b);
   RefreshAfterMouseMoved = YES;
   [self setNeedsDisplayInRect:ab];
于 2009-12-25T10:43:27.273 に答える