Как обновить раздел NSView без перерисовки всего представления - PullRequest
2 голосов
/ 23 декабря 2009

У меня есть NSView, где я рисую тысячи NSBezierPaths. Я хотел бы выделить (изменить цвет заливки) выбранное событие мыши. На данный момент я использую в функции mouseMoved следующую команду:

     [self setsetNeedsDisplay:YES];

, которые заставляют вызов drawRect перерисовывать каждый путь. Я хотел бы перерисовать только выбранный. Я пытался использовать addClip в функции drawRect:

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

но похоже, что drawRect уничтожает все другие ранее нарисованные пути и перерисовывает только один обрезанный.

Возможно ли НЕ аннулировать все представления при вызове drawRect? Я имею в виду просто постепенно переписать то, что было на представлении раньше?

Спасибо, Лука

Ответы [ 2 ]

4 голосов
/ 23 декабря 2009

Вы должны использовать [self setNeedsDisplayInRect:…]. Передайте NSRect, который вы хотите сделать недействительным, и это будет область, переданная вызову drawRect:.

Внутри drawRect:, проверьте область, которая была передана, и выполните только рисование, необходимое внутри этого прямоугольника.

Кроме того, вы можете захотеть использовать NSTrackingArea вместо mouseMoved: - это позволит вам настроить определенные прямоугольники для запуска обновлений.

1 голос
/ 25 декабря 2009

Я думаю, что решил быстрее, так как я априори не знаю, какие пути присутствуют в прямоугольнике, и я хочу избежать цикла по всем путям. К счастью, мои пути меняются не часто, поэтому я могу кэшировать все пути в 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];
...