Skip to content

Commit 5537f38

Browse files
committed
Show HUD while exporting, and show UIActivityViewController afterwards
1 parent b27d6d6 commit 5537f38

3 files changed

Lines changed: 108 additions & 3 deletions

File tree

Source/TriangleDrawMain/Canvas/Menu/HCMenuView.swift

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,48 @@
11
// MIT license. Copyright (c) 2023 TriangleDraw. All rights reserved.
22
import SwiftUI
33
import TriangleDrawLibrary
4+
import TTProgressHUD
5+
6+
enum ShareData {
7+
case none
8+
case exportPNG(image: UIImage, filename: String?)
9+
}
410

511
struct HCMenuView: View {
612
@ObservedObject var model: HCMenuViewModel
713
@Environment(\.dismiss) var dismiss
814
@State private var gridMode: CanvasGridMode
915
@State private var symmetryMode: SymmetryMode
16+
@State private var hudVisible = false
17+
@State private var hudConfig = TTProgressHUDConfig(title: "Exporting")
18+
@State private var isSharePresented: Bool = false
19+
@State private var shareData: ShareData = .none
1020

1121
init(model: HCMenuViewModel) {
1222
self.model = model
1323
self._gridMode = State(initialValue: model.initialGridMode)
1424
self._symmetryMode = State(initialValue: model.initialSymmetryMode)
1525
}
1626

27+
var exportPNGButton: some View {
28+
Button("Bitmap PNG") {
29+
hudVisible = true
30+
model.exportToPNG() { status in
31+
switch status {
32+
case let HCMenuViewModel.ExportPNGStatus.ok(image, filename):
33+
hudVisible = false
34+
self.shareData = ShareData.exportPNG(image: image, filename: filename)
35+
self.isSharePresented = true
36+
case HCMenuViewModel.ExportPNGStatus.progress(let progress):
37+
log.debug("progress: \(progress)")
38+
case HCMenuViewModel.ExportPNGStatus.error(let message):
39+
log.error("Unable to export to PNG. \(message)")
40+
hudVisible = false
41+
}
42+
}
43+
}
44+
}
45+
1746
var emailDeveloperButton: some View {
1847
#if os(iOS)
1948
let view = MailButtonView(
@@ -25,7 +54,7 @@ struct HCMenuView: View {
2554
#endif
2655
}
2756

28-
var body: some View {
57+
var navigationStack: some View {
2958
NavigationStack {
3059
Form {
3160
Section(header: Text("Grid system")) {
@@ -51,7 +80,7 @@ struct HCMenuView: View {
5180
}
5281
}
5382
Section(header: Text("Export")) {
54-
Button("Bitmap PNG") {}
83+
exportPNGButton
5584
Button("Vector PDF") {}
5685
Button("Vector SVG") {}
5786
}
@@ -70,6 +99,37 @@ struct HCMenuView: View {
7099
}
71100
}.navigationViewStyle(.stack)
72101
}
102+
103+
var body: some View {
104+
ZStack(alignment: .top) {
105+
navigationStack
106+
TTProgressHUD($hudVisible, config: hudConfig)
107+
}
108+
.sheet(isPresented: $isSharePresented, onDismiss: {
109+
log.debug("dismiss ActivityViewController")
110+
shareData = .none
111+
}, content: {
112+
ActivityViewController(shareData: $shareData)
113+
})
114+
}
115+
}
116+
117+
struct ActivityViewController: UIViewControllerRepresentable {
118+
@Binding var shareData: ShareData
119+
120+
func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityViewController>) -> UIActivityViewController {
121+
switch shareData {
122+
case .none:
123+
log.debug("share: none")
124+
let activityItems = [URL(string: "http://www.triangledraw.com/")!]
125+
return UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
126+
case let .exportPNG(image, filename):
127+
log.debug("share: png")
128+
return HCMenuViewController.createSharePNGActivityViewController(image: image, filename: filename, triangleCount: 0)
129+
}
130+
}
131+
132+
func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext<ActivityViewController>) {}
73133
}
74134

75135
struct HCMenuView_Previews: PreviewProvider {

Source/TriangleDrawMain/Canvas/Menu/HCMenuViewController.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ class HCMenuViewController: RFFormViewController {
5555
static func create(document: HexagonCanvasMenuDocument, delegate: HCMenuViewControllerDelegate?) -> UIViewController {
5656
let model = HCMenuViewModel.create()
5757
model.delegate = delegate
58+
59+
switch document {
60+
case let .document(document):
61+
model.initialCanvas = document.canvas
62+
model.document_displayName = document.displayName
63+
case .mock:
64+
model.initialCanvas = DocumentExample.triangledrawLogo.canvas
65+
model.document_displayName = "Mock"
66+
}
67+
5868
let rootView = HCMenuView(model: model)
5969
return UIHostingController(rootView: rootView)
6070
}
@@ -301,7 +311,7 @@ extension HCMenuViewController: HCMenuSubdivideViewControllerDelegate {
301311
}
302312

303313
extension E2Canvas {
304-
fileprivate func computeTriangleCount() -> UInt {
314+
func computeTriangleCount() -> UInt {
305315
// swiftlint:disable identifier_name
306316
let n1: UInt = self.numberOfDifferences(from: E2Canvas.createBigCanvas())
307317
let n2: UInt = self.numberOfDifferences(from: E2Canvas.bigCanvasMask())

Source/TriangleDrawMain/Canvas/Menu/HCMenuViewModel.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@ public class HCMenuViewModel: ObservableObject {
88
weak var delegate: HCMenuViewControllerDelegate?
99
var initialGridMode: CanvasGridMode
1010
var initialSymmetryMode: SymmetryMode
11+
var initialCanvas: E2Canvas?
12+
13+
// swiftlint:disable:next identifier_name
14+
var document_displayName: String?
1115

1216
init() {
1317
self.delegate = nil
1418
self.initialGridMode = CanvasGridMode.smallFixedSizeDots
1519
self.initialSymmetryMode = SymmetryMode.noSymmetry
20+
self.initialCanvas = nil
21+
self.document_displayName = nil
1622
}
1723

1824
static func create() -> HCMenuViewModel {
@@ -21,4 +27,33 @@ public class HCMenuViewModel: ObservableObject {
2127
instance.initialSymmetryMode = globalSymmetryMode
2228
return instance
2329
}
30+
31+
public enum ExportPNGStatus {
32+
case progress(progress: Float)
33+
case ok(image: UIImage, filename: String?)
34+
case error(message: String)
35+
}
36+
37+
func exportToPNG(callback: @escaping (ExportPNGStatus) -> Void) {
38+
guard let canvas: E2Canvas = self.initialCanvas else {
39+
callback(ExportPNGStatus.error(message: "exportToPNG - Expected document.canvas to be non-nil, but got nil"))
40+
return
41+
}
42+
log.debug("exportToPNG initiate")
43+
let t0 = CFAbsoluteTimeGetCurrent()
44+
let filename = document_displayName ?? ""
45+
46+
TDRenderBitmap.imageWithSize2048x2048(for: canvas, progress: { progress in
47+
callback(ExportPNGStatus.progress(progress: progress))
48+
}) { imageOrNil in // swiftlint:disable:this multiple_closures_with_trailing_closure
49+
guard let image: UIImage = imageOrNil else {
50+
callback(ExportPNGStatus.error(message: "exportToPNG - Expected TDRenderBitmap to generate an image, but got nil"))
51+
return
52+
}
53+
let t1 = CFAbsoluteTimeGetCurrent()
54+
let elapsed: Double = t1 - t0
55+
log.debug("exportToPNG - ready for sharing. elapsed: \(elapsed.string2)")
56+
callback(ExportPNGStatus.ok(image: image, filename: filename))
57+
}
58+
}
2459
}

0 commit comments

Comments
 (0)