Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Modules/Legacy/Core/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,12 @@
"ToolPickerItem.magicToolItem" = "Magic Highlighter";
// Menu item for the manual highlighter tool
"ToolPickerItem.manualToolItem" = "Manual Highlighter";

// Label for the zoom in toolbar item
"ZoomInItem.label" = "Zoom In";

// Label for the zoom toolbar item group
"ZoomItemGroup.label" = "Zoom";

// Label for the zoom out toolbar item
"ZoomOutItem.label" = "Zoom Out";
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Created by Geoff Pado on 9/2/25.
// Copyright © 2025 Cocoatype, LLC. All rights reserved.

#if targetEnvironment(macCatalyst)
import Foundation

class ZoomInItem: NSToolbarItem {
static let identifier = NSToolbarItem.Identifier("ZoomInItem.identifier")
let delegate: ZoomItemDelegate

init(delegate: ZoomItemDelegate) {
self.delegate = delegate
super.init(itemIdentifier: Self.identifier)

image = UIImage(systemName: "plus.magnifyingglass")?
.applyingSymbolConfiguration(.init(scale: .large))
isBordered = true
label = CoreStrings.ZoomInItem.label

target = delegate
action = #selector(ZoomItemDelegate.zoomIn(_:))
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Created by Geoff Pado on 9/2/25.
// Copyright © 2025 Cocoatype, LLC. All rights reserved.

#if targetEnvironment(macCatalyst)
@objc @MainActor protocol ZoomItemDelegate: AnyObject {
@objc func zoomIn(_ sender: NSToolbarItem)
@objc func zoomOut(_ sender: NSToolbarItem)
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Created by Geoff Pado on 9/2/25.
// Copyright © 2025 Cocoatype, LLC. All rights reserved.

#if targetEnvironment(macCatalyst)
import Foundation

class ZoomItemGroup: NSToolbarItemGroup {
static let identifier = NSToolbarItem.Identifier("ZoomItemGroup.identifier")

static let zoomStops = [
0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.75, 1.0, 1.5,
2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0,
12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0,
22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0,
]

init(delegate: any ZoomItemDelegate) {
super.init(itemIdentifier: Self.identifier)
label = CoreStrings.ZoomItemGroup.label
subitems = [ZoomOutItem(delegate: delegate), ZoomInItem(delegate: delegate)]
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Created by Geoff Pado on 9/2/25.
// Copyright © 2025 Cocoatype, LLC. All rights reserved.

#if targetEnvironment(macCatalyst)
import Foundation

class ZoomOutItem: NSToolbarItem {
static let identifier = NSToolbarItem.Identifier("ZoomOutItem.identifier")
let delegate: ZoomItemDelegate

init(delegate: ZoomItemDelegate) {
self.delegate = delegate
super.init(itemIdentifier: Self.identifier)

image = UIImage(systemName: "minus.magnifyingglass")?
.applyingSymbolConfiguration(.init(scale: .large))
isBordered = true
label = CoreStrings.ZoomOutItem.label

target = delegate
action = #selector(ZoomItemDelegate.zoomOut(_:))
}
}
#endif
27 changes: 26 additions & 1 deletion Modules/Legacy/Core/Sources/Scene/DesktopSceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import Tools
import UserActivities

#if targetEnvironment(macCatalyst)
class DesktopSceneDelegate: NSObject, UIWindowSceneDelegate, NSToolbarDelegate, ShareItemDelegate, ToolPickerItemDelegate, ColorPickerItemDelegate, SeekItemDelegate {
class DesktopSceneDelegate: NSObject, UIWindowSceneDelegate, NSToolbarDelegate, ShareItemDelegate,
ToolPickerItemDelegate, ColorPickerItemDelegate, SeekItemDelegate, ZoomItemDelegate {
var window: DesktopAppWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
Expand Down Expand Up @@ -87,10 +88,31 @@ class DesktopSceneDelegate: NSObject, UIWindowSceneDelegate, NSToolbarDelegate,
editingViewController?.toggleSeeking(sender)
}

// MARK: ZoomItemDelegate

func zoomIn(_ sender: NSToolbarItem) {
guard let editingViewController else { return }
let currentScale = editingViewController.zoomScale
editingViewController.zoomScale = ZoomItemGroup.zoomStops.first(where: {
$0 > currentScale
}) ?? ZoomItemGroup.zoomStops.last ?? currentScale
print("zoom scale is \(editingViewController.zoomScale)")
}

func zoomOut(_ sender: NSToolbarItem) {
guard let editingViewController else { return }
let currentScale = editingViewController.zoomScale
editingViewController.zoomScale = ZoomItemGroup.zoomStops.reversed().first(where: {
$0 < currentScale
}) ?? ZoomItemGroup.zoomStops.first ?? currentScale
print("zoom scale is \(editingViewController.zoomScale)")
}

// MARK: NSToolbarDelegate

func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
[
ZoomItemGroup.identifier,
SeekItem.identifier,
ColorPickerItem.identifier,
ToolPickerItem.identifier,
Expand All @@ -108,6 +130,9 @@ class DesktopSceneDelegate: NSObject, UIWindowSceneDelegate, NSToolbarDelegate,
case ShareItem.identifier: return ShareItem(delegate: self)
case ColorPickerItem.identifier: return ColorPickerItem(delegate: self)
case SeekItem.identifier: return SeekItem(delegate: self)
case ZoomInItem.identifier: return ZoomInItem(delegate: self)
case ZoomOutItem.identifier: return ZoomOutItem(delegate: self)
case ZoomItemGroup.identifier: return ZoomItemGroup(delegate: self)
default: return nil
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,13 @@ public class PhotoEditingViewController: UIViewController, UIScrollViewDelegate,
return wordObservations + categoryObservations
}

// MARK: Zoom

public var zoomScale: CGFloat {
get { photoEditingView.zoomScale }
set { photoEditingView.setZoomScale(newValue, animated: true) }
}

// MARK: User Activity

open override func updateUserActivityState(_ activity: NSUserActivity) {
Expand Down