From e0793b8acade7ee0cf1e0dd737227118247b4cdd Mon Sep 17 00:00:00 2001 From: Felipe Espinoza Date: Thu, 13 Jul 2017 01:08:15 +0200 Subject: [PATCH] CanvasView: optimize rendering (#64) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Only re-draw elements that are inside the dirtyRect. previously for each dirty rect I re-rendered the whole set of concepts. - Mark view as opaque so the OS doesn’t need to render views under. --- LinkedIdeas/CanvasView.swift | 23 +++++++++++-------- ...sViewController+CanvasViewDataSource.swift | 4 ++++ ...CanvasViewController+DraggingActions.swift | 2 +- LinkedIdeas/Document.swift | 4 ++++ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/LinkedIdeas/CanvasView.swift b/LinkedIdeas/CanvasView.swift index f8c6c48..c1c0326 100644 --- a/LinkedIdeas/CanvasView.swift +++ b/LinkedIdeas/CanvasView.swift @@ -10,10 +10,13 @@ import Cocoa public protocol CanvasViewDataSource { var drawableElements: [DrawableElement] { get } + + func drawableElements(forRect: NSRect) -> [DrawableElement] } public class CanvasView: NSView { + public override var isOpaque: Bool { return true } public var dataSource: CanvasViewDataSource? var selectFromPoint: NSPoint? @@ -34,20 +37,23 @@ public class CanvasView: NSView { override public func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) - drawBackground() + drawBackground(dirtyRect) + drawElements(inRect: dirtyRect) + drawSelectionRect() + drawLinkConstructionArrow() + } - if let dataSource = dataSource { - for element in dataSource.drawableElements { element.draw() } + func drawElements(inRect dirtyRect: NSRect) { + guard let dataSource = dataSource else { + return } - drawSelectionRect() - - drawLinkConstructionArrow() + dataSource.drawableElements(forRect: dirtyRect).forEach({ $0.draw() }) } - func drawBackground() { + func drawBackground(_ dirtyRect: NSRect) { NSColor.white.set() - NSRectFill(bounds) + NSRectFill(dirtyRect) } func drawSelectionRect() { @@ -57,7 +63,6 @@ public class CanvasView: NSView { let borderColor = NSColor(red: 0, green: 0, blue: 1, alpha: 1) let backgroundColor = NSColor(red: 0, green: 0, blue: 1, alpha: 0.5) - let bezierPath = NSBezierPath(rect: selectionRect) borderColor.set() diff --git a/LinkedIdeas/CanvasViewController+CanvasViewDataSource.swift b/LinkedIdeas/CanvasViewController+CanvasViewDataSource.swift index cef00cd..8ed24c3 100644 --- a/LinkedIdeas/CanvasViewController+CanvasViewDataSource.swift +++ b/LinkedIdeas/CanvasViewController+CanvasViewDataSource.swift @@ -24,4 +24,8 @@ extension CanvasViewController: CanvasViewDataSource { return elements } + + func drawableElements(forRect containerRect: NSRect) -> [DrawableElement] { + return drawableElements.filter({ containerRect.intersects($0.drawingBounds) }) + } } diff --git a/LinkedIdeas/CanvasViewController+DraggingActions.swift b/LinkedIdeas/CanvasViewController+DraggingActions.swift index 22dc83a..39e4891 100644 --- a/LinkedIdeas/CanvasViewController+DraggingActions.swift +++ b/LinkedIdeas/CanvasViewController+DraggingActions.swift @@ -120,6 +120,6 @@ extension CanvasViewController { dragCount = 0 canvasView.selectFromPoint = nil canvasView.selectToPoint = nil - canvasView.needsDisplay = true + reRenderCanvasView() } } diff --git a/LinkedIdeas/Document.swift b/LinkedIdeas/Document.swift index 14af538..6569813 100644 --- a/LinkedIdeas/Document.swift +++ b/LinkedIdeas/Document.swift @@ -194,6 +194,10 @@ extension Document: LinkedIdeasDocument { } extension Document: CanvasViewDataSource { + public func drawableElements(forRect: NSRect) -> [DrawableElement] { + return drawableElements + } + public var drawableElements: [DrawableElement] { var elements: [DrawableElement] = []