feat: sync render view port with scrollview

This commit is contained in:
dscyrescotti
2024-07-07 13:37:45 +07:00
parent cbd2e4c484
commit 739aaa059b
8 changed files with 91 additions and 35 deletions
@@ -10,11 +10,7 @@ import Foundation
struct PointGridVertex {
var position: vector_float4
#if os(macOS)
var pointSize: Float = 256
#else
var pointSize: Float = 10
#endif
}
extension PointGridVertex {
+11 -6
View File
@@ -110,8 +110,9 @@ extension Canvas {
let bounds = CGRect(origin: .zero, size: size)
let renderView = drawingView.renderView
#if os(macOS)
let drawingViewBounds = CGRect(origin: .zero, size: drawingView.bounds.size.multiply(by: zoomScale))
let targetRect = drawingView.convert(drawingViewBounds, to: renderView)
let drawingViewBounds = drawingView.bounds
var targetRect = drawingView.convert(drawingViewBounds, to: renderView)
targetRect.origin.y = renderView.bounds.height - targetRect.maxY
#else
let targetRect = drawingView.convert(drawingView.bounds, to: renderView)
#endif
@@ -145,19 +146,23 @@ extension Canvas {
}
func updateClipBounds(_ scrollView: Platform.ScrollView, on drawingView: DrawingView) {
#if os(macOS)
let ratio = drawingView.ratio
var bounds = scrollView.convert(scrollView.bounds, to: drawingView)
bounds.origin.y = drawingView.bounds.height - (bounds.origin.y + bounds.height)
clipBounds = CGRect(origin: bounds.origin.muliply(by: ratio), size: bounds.size.multiply(by: ratio))
#else
let ratio = drawingView.ratio
let bounds = scrollView.convert(scrollView.bounds, to: drawingView)
clipBounds = CGRect(origin: bounds.origin.muliply(by: ratio), size: bounds.size.multiply(by: ratio))
#endif
}
}
// MARK: - Zoom Scale
extension Canvas {
func setZoomScale(_ zoomScale: CGFloat) {
DispatchQueue.main.async { [weak self] in
guard let self else { return }
self.zoomScale = min(max(zoomScale, minimumZoomScale), maximumZoomScale)
}
self.zoomScale = min(max(zoomScale, minimumZoomScale), maximumZoomScale)
}
}
+1 -1
View File
@@ -112,7 +112,7 @@ final class Renderer {
func drawPreview(on canvas: Canvas) -> Platform.Image? {
guard let commandBuffer = commandQueue.makeCommandBuffer() else {
NSLog("[Memola] - Unable to create command buffer")
NSLog("[Memola] - Unable to create command buffer for preview")
return nil
}
strokeRenderPass.eraserRenderPass = eraserRenderPass
@@ -48,14 +48,11 @@ class CanvasViewController: Platform.ViewController {
}
#if os(macOS)
override func viewWillLayout() {
super.viewWillLayout()
resizeDocumentView()
updateDocumentBounds()
}
override func viewWillAppear() {
super.viewWillAppear()
resizeDocumentView()
updateDocumentBounds()
loadMemo()
}
@@ -132,9 +129,9 @@ extension CanvasViewController {
scrollView.isScrollEnabled = true
scrollView.showsVerticalScrollIndicator = true
scrollView.showsHorizontalScrollIndicator = true
scrollView.delegate = self
scrollView.backgroundColor = .clear
#endif
scrollView.delegate = self
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
@@ -146,7 +143,7 @@ extension CanvasViewController {
])
#if os(macOS)
scrollView.contentView = CenterClipView()
scrollView.contentView = NSCenterClipView()
scrollView.contentView.drawsBackground = false
scrollView.documentView = drawingView
#else
@@ -171,10 +168,14 @@ extension CanvasViewController {
let height = size.height * scale
let newFrame = CGRect(x: 0, y: 0, width: width, height: height)
drawingView.frame = newFrame
DispatchQueue.main.async { [unowned canvas] in
canvas.setZoomScale(canvas.defaultZoomScale)
}
#if os(macOS)
let rect = scrollView.documentVisibleRect
let center = NSPoint(x: rect.midX, y: rect.midY)
scrollView.contentView.setBoundsSize(newFrame.size)
let center = NSPoint(x: newFrame.midX, y: newFrame.midY)
scrollView.setMagnification(canvas.defaultZoomScale, centeredAt: center)
#else
scrollView.setZoomScale(canvas.defaultZoomScale, animated: true)
@@ -189,7 +190,6 @@ extension CanvasViewController {
scrollView.setContentOffset(point, animated: true)
#endif
drawingView.updateDrawableSize(with: view.frame.size)
NSLog("[Memola] - drawingView: \(drawingView.frame.size.multiply(by: scrollView.magnification)), scrollView: \(scrollView.frame), renderView: \(renderView.frame)")
}
#if os(iOS)
@@ -204,7 +204,10 @@ extension CanvasViewController {
func updateDocumentBounds() {
#if os(macOS)
var bounds = scrollView.bounds.muliply(by: drawingView.ratio / scrollView.magnification)
let ratio = drawingView.ratio
var bounds = scrollView.convert(scrollView.bounds, to: drawingView)
bounds.origin.y = drawingView.bounds.height - (bounds.origin.y + bounds.height)
bounds = CGRect(origin: bounds.origin.muliply(by: ratio), size: bounds.size.multiply(by: ratio))
#else
var bounds = scrollView.bounds.muliply(by: drawingView.ratio / scrollView.zoomScale)
#endif
@@ -226,6 +229,7 @@ extension CanvasViewController {
#if os(macOS)
NotificationCenter.default.publisher(for: NSScrollView.didEndLiveMagnifyNotification, object: scrollView)
.sink { [weak self] _ in
self?.updateDocumentBounds()
self?.magnificationEnded()
}
.store(in: &cancellables)
@@ -241,6 +245,7 @@ extension CanvasViewController {
.store(in: &cancellables)
NotificationCenter.default.publisher(for: NSScrollView.didEndLiveScrollNotification, object: scrollView)
.sink { [weak self] _ in
self?.updateDocumentBounds()
self?.draggingEnded()
}
.store(in: &cancellables)
@@ -334,7 +339,12 @@ extension CanvasViewController {
withAnimation {
tool.selectedPhotoItem = nil
}
#if os(macOS)
let pointInLeftBottomOrigin = gesture.location(in: drawingView)
let point = CGPoint(x: pointInLeftBottomOrigin.x, y: drawingView.bounds.height - pointInLeftBottomOrigin.y)
#else
let point = gesture.location(in: drawingView)
#endif
let photo = canvas.insertPhoto(at: point.muliply(by: drawingView.ratio), photoItem: photoItem)
history.addUndo(.photo(photo))
drawingView.draw()
@@ -342,6 +352,16 @@ extension CanvasViewController {
}
#if os(macOS)
extension CanvasViewController: NSSyncScrollViewDelegate {
func scrollViewDidZoom(_ scrollView: NSSyncScrollView) {
canvas.setZoomScale(scrollView.magnification)
renderView.draw()
}
func scrollViewDidScroll(_ scrollView: NSSyncScrollView) {
renderView.draw()
}
}
#else
extension CanvasViewController: UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
@@ -392,9 +412,6 @@ extension CanvasViewController: UIScrollViewDelegate {
extension CanvasViewController {
func magnificationStarted() {
#if os(macOS)
canvas.setZoomScale(scrollView.magnification)
#endif
guard !renderer.updatesViewPort else { return }
drawingView.touchCancelled()
canvas.updateClipBounds(scrollView, on: drawingView)
@@ -403,9 +420,6 @@ extension CanvasViewController {
}
func magnificationEnded() {
#if os(macOS)
canvas.setZoomScale(scrollView.magnification)
#endif
renderer.setUpdatesViewPort(false)
renderer.setRedrawsGraphicRender()
renderView.draw()
@@ -1,5 +1,5 @@
//
// CenterClipView.swift
// NSCenterClipView.swift
// Memola
//
// Created by Dscyre Scotti on 7/6/24.
@@ -8,7 +8,7 @@
#if canImport(AppKit)
import AppKit
class CenterClipView: NSClipView {
class NSCenterClipView: NSClipView {
override func constrainBoundsRect(_ proposedBounds: NSRect) -> NSRect {
var rect = super.constrainBoundsRect(proposedBounds)
if let containerView = self.documentView {
@@ -0,0 +1,29 @@
//
// NSSyncScrollView.swift
// Memola
//
// Created by Dscyre Scotti on 7/6/24.
//
#if canImport(AppKit)
import AppKit
protocol NSSyncScrollViewDelegate: AnyObject {
func scrollViewDidZoom(_ scrollView: NSSyncScrollView)
func scrollViewDidScroll(_ scrollView: NSSyncScrollView)
}
class NSSyncScrollView: NSScrollView {
weak var delegate: NSSyncScrollViewDelegate?
override func magnify(with event: NSEvent) {
super.magnify(with: event)
delegate?.scrollViewDidZoom(self)
}
override func scrollWheel(with event: NSEvent) {
super.scrollWheel(with: event)
delegate?.scrollViewDidScroll(self)
}
}
#endif
+1 -1
View File
@@ -12,7 +12,7 @@ enum Platform {
typealias View = NSView
typealias Color = NSColor
typealias Image = NSImage
typealias ScrollView = NSScrollView
typealias ScrollView = NSSyncScrollView
typealias Application = NSApplication
typealias ViewController = NSViewController
typealias TapGestureRecognizer = NSClickGestureRecognizer