@imgly/editor-react-native 1.73.0 → 1.73.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +1 -1
- package/android/src/main/assets/scene/apparel.scene +1 -0
- package/android/src/main/assets/scene/design.scene +1 -0
- package/android/src/main/assets/scene/postcard.scene +1 -0
- package/android/src/main/assets/scene/video.scene +1 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/apparel/ApparelConfigurationBuilder.kt +113 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/apparel/EditorActivity.kt +37 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/apparel/callback/OnCreate.kt +190 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/apparel/callback/OnExport.kt +82 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/apparel/callback/OnLoaded.kt +88 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/apparel/component/CanvasMenu.kt +45 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/apparel/component/Dock.kt +37 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/apparel/component/InspectorBar.kt +52 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/apparel/component/NavigationBar.kt +45 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/apparel/component/Overlay.kt +15 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/design/DesignConfigurationBuilder.kt +106 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/design/EditorActivity.kt +37 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/design/callback/OnCreate.kt +162 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/design/callback/OnExport.kt +82 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/design/callback/OnLoaded.kt +10 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/design/component/CanvasMenu.kt +45 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/design/component/Dock.kt +35 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/design/component/InspectorBar.kt +52 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/design/component/NavigationBar.kt +45 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/design/component/Overlay.kt +15 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/photo/EditorActivity.kt +37 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/photo/PhotoConfigurationBuilder.kt +106 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/photo/callback/OnCreate.kt +143 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/photo/callback/OnExport.kt +82 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/photo/callback/OnLoaded.kt +49 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/photo/component/CanvasMenu.kt +45 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/photo/component/Dock.kt +43 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/photo/component/InspectorBar.kt +52 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/photo/component/NavigationBar.kt +45 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/photo/component/Overlay.kt +15 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/postcard/EditorActivity.kt +37 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/postcard/PostcardConfigurationBuilder.kt +106 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/postcard/callback/OnCreate.kt +149 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/postcard/callback/OnExport.kt +82 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/postcard/callback/OnLoaded.kt +58 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/postcard/component/CanvasMenu.kt +45 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/postcard/component/Dock.kt +243 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/postcard/component/InspectorBar.kt +52 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/postcard/component/NavigationBar.kt +76 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/postcard/component/Overlay.kt +15 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/postcard/ext/Engine.kt +107 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/EditorActivity.kt +37 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/VideoConfigurationBuilder.kt +135 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/callback/OnCreate.kt +191 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/callback/OnExport.kt +98 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/callback/OnLoaded.kt +20 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/component/BottomPanel.kt +13 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/component/CanvasMenu.kt +45 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/component/Dock.kt +71 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/component/InspectorBar.kt +68 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/component/NavigationBar.kt +57 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/component/Overlay.kt +421 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/iconPack/CheckCircleOutline.kt +79 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/iconPack/ErrorOutline.kt +92 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/iconPack/IconPack.kt +14 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/model/ExportStatus.kt +39 -0
- package/ios/IMGLYEditorModule.swift +9 -1
- package/ios/StarterKits/Apparel/ApparelEditorConfiguration.swift +46 -0
- package/ios/StarterKits/Apparel/ApparelEditorStarterKit.swift +30 -0
- package/ios/StarterKits/Apparel/callbacks/OnChanged+Apparel.swift +116 -0
- package/ios/StarterKits/Apparel/callbacks/OnCreate+Apparel.swift +197 -0
- package/ios/StarterKits/Apparel/callbacks/OnExport+Apparel.swift +29 -0
- package/ios/StarterKits/Apparel/components/CanvasMenu+Apparel.swift +22 -0
- package/ios/StarterKits/Apparel/components/Dock+Apparel.swift +19 -0
- package/ios/StarterKits/Apparel/components/InspectorBar+Apparel.swift +35 -0
- package/ios/StarterKits/Apparel/components/NavigationBar+Apparel.swift +26 -0
- package/ios/StarterKits/Design/DesignEditorConfiguration.swift +43 -0
- package/ios/StarterKits/Design/DesignEditorStarterKit.swift +30 -0
- package/ios/StarterKits/Design/callbacks/OnCreate+Design.swift +131 -0
- package/ios/StarterKits/Design/callbacks/OnExport+Design.swift +30 -0
- package/ios/StarterKits/Design/components/CanvasMenu+Design.swift +22 -0
- package/ios/StarterKits/Design/components/Dock+Design.swift +23 -0
- package/ios/StarterKits/Design/components/InspectorBar+Design.swift +35 -0
- package/ios/StarterKits/Design/components/NavigationBar+Design.swift +24 -0
- package/ios/StarterKits/Photo/PhotoEditorConfiguration.swift +48 -0
- package/ios/StarterKits/Photo/PhotoEditorStarterKit.swift +30 -0
- package/ios/StarterKits/Photo/callbacks/OnChanged+Photo.swift +25 -0
- package/ios/StarterKits/Photo/callbacks/OnCreate+Photo.swift +138 -0
- package/ios/StarterKits/Photo/callbacks/OnExport+Photo.swift +29 -0
- package/ios/StarterKits/Photo/callbacks/OnLoaded+Photo.swift +18 -0
- package/ios/StarterKits/Photo/components/CanvasMenu+Photo.swift +22 -0
- package/ios/StarterKits/Photo/components/Dock+Photo.swift +23 -0
- package/ios/StarterKits/Photo/components/InspectorBar+Photo.swift +39 -0
- package/ios/StarterKits/Photo/components/NavigationBar+Photo.swift +24 -0
- package/ios/StarterKits/Photo/examples/ExampleForceCrop.swift +30 -0
- package/ios/StarterKits/Postcard/PostcardEditorConfiguration.swift +45 -0
- package/ios/StarterKits/Postcard/PostcardEditorStarterKit.swift +30 -0
- package/ios/StarterKits/Postcard/callbacks/OnChanged+Postcard.swift +92 -0
- package/ios/StarterKits/Postcard/callbacks/OnCreate+Postcard.swift +127 -0
- package/ios/StarterKits/Postcard/callbacks/OnExport+Postcard.swift +29 -0
- package/ios/StarterKits/Postcard/components/CanvasMenu+Postcard.swift +22 -0
- package/ios/StarterKits/Postcard/components/Dock+Postcard.swift +34 -0
- package/ios/StarterKits/Postcard/components/DockButtons+Postcard.swift +129 -0
- package/ios/StarterKits/Postcard/components/InspectorBar+Postcard.swift +35 -0
- package/ios/StarterKits/Postcard/components/NavigationBar+Postcard.swift +38 -0
- package/ios/StarterKits/Video/VideoEditorConfiguration.swift +54 -0
- package/ios/StarterKits/Video/VideoEditorStarterKit.swift +30 -0
- package/ios/StarterKits/Video/callbacks/OnCreate+Video.swift +137 -0
- package/ios/StarterKits/Video/callbacks/OnExport+Video.swift +46 -0
- package/ios/StarterKits/Video/components/BottomPanel+Video.swift +16 -0
- package/ios/StarterKits/Video/components/CanvasMenu+Video.swift +22 -0
- package/ios/StarterKits/Video/components/Dock+Video.swift +30 -0
- package/ios/StarterKits/Video/components/InspectorBar+Video.swift +43 -0
- package/ios/StarterKits/Video/components/NavigationBar+Video.swift +32 -0
- package/ios/StarterKits/Video/examples/ExampleVideoDurationConstraints.swift +23 -0
- package/ios/StarterKits/apparel-ui-b-empty.scene +1 -0
- package/ios/StarterKits/design-ui-empty.scene +1 -0
- package/ios/StarterKits/photo-ui-empty.png +0 -0
- package/ios/StarterKits/postcard-empty.scene +1 -0
- package/ios/StarterKits/video-empty.scene +1 -0
- package/package.json +1 -1
- package/src/NativeIMGLYEditor.ts +1 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
|
|
3
|
+
// MARK: - Canvas Menu
|
|
4
|
+
|
|
5
|
+
extension PostcardEditorConfiguration {
|
|
6
|
+
/// The default canvas menu configuration.
|
|
7
|
+
static var defaultCanvasMenu: CanvasMenu.Configuration {
|
|
8
|
+
CanvasMenu.Configuration { builder in
|
|
9
|
+
// highlight-starter-kit-canvas-menu
|
|
10
|
+
builder.items { _ in
|
|
11
|
+
CanvasMenu.Buttons.selectGroup()
|
|
12
|
+
CanvasMenu.Divider()
|
|
13
|
+
CanvasMenu.Buttons.bringForward()
|
|
14
|
+
CanvasMenu.Buttons.sendBackward()
|
|
15
|
+
CanvasMenu.Divider()
|
|
16
|
+
CanvasMenu.Buttons.duplicate()
|
|
17
|
+
CanvasMenu.Buttons.delete()
|
|
18
|
+
}
|
|
19
|
+
// highlight-starter-kit-canvas-menu
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
import SwiftUI
|
|
3
|
+
|
|
4
|
+
// MARK: - Dock
|
|
5
|
+
|
|
6
|
+
extension PostcardEditorConfiguration {
|
|
7
|
+
/// The default dock configuration.
|
|
8
|
+
static var defaultDock: Dock.Configuration {
|
|
9
|
+
Dock.Configuration { builder in
|
|
10
|
+
// highlight-starter-kit-dock
|
|
11
|
+
builder.items { _ in
|
|
12
|
+
Dock.Buttons
|
|
13
|
+
.assetLibrary(
|
|
14
|
+
isVisible: { try $0.engine.scene.getPages().first == $0.engine.scene.getCurrentPage() },
|
|
15
|
+
modifier: { _ in Dock.Buttons.AssetLibraryModifier() },
|
|
16
|
+
)
|
|
17
|
+
Dock.Custom(id: "ly.img.component.dock.postcard.divider", content: { _ in
|
|
18
|
+
Divider()
|
|
19
|
+
.frame(height: 40)
|
|
20
|
+
.padding(.leading, 8)
|
|
21
|
+
}, isVisible: { try $0.engine.scene.getPages().first == $0.engine.scene.getCurrentPage() })
|
|
22
|
+
Dock.Buttons.designColors()
|
|
23
|
+
Dock.Buttons.greetingFont()
|
|
24
|
+
Dock.Buttons.greetingSize()
|
|
25
|
+
Dock.Buttons.greetingColors()
|
|
26
|
+
}
|
|
27
|
+
builder.alignment = {
|
|
28
|
+
try $0.engine.scene.getPages().first == $0.engine.scene.getCurrentPage() ? .leading : .center
|
|
29
|
+
}
|
|
30
|
+
builder.scrollDisabled = { _ in true }
|
|
31
|
+
// highlight-starter-kit-dock
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
@_spi(Internal) import IMGLYEditor
|
|
2
|
+
import IMGLYEngine
|
|
3
|
+
import SwiftUI
|
|
4
|
+
|
|
5
|
+
// MARK: - Dock Button IDs
|
|
6
|
+
|
|
7
|
+
extension Dock.Buttons.ID {
|
|
8
|
+
/// The id of the ``Dock/Buttons/designColors(action:title:icon:isEnabled:isVisible:)`` button.
|
|
9
|
+
static var designColors: EditorComponentID { "ly.img.component.dock.button.postcard.designColors" }
|
|
10
|
+
/// The id of the ``Dock/Buttons/greetingColors(action:title:icon:isEnabled:isVisible:)`` button.
|
|
11
|
+
static var greetingColors: EditorComponentID { "ly.img.component.dock.button.postcard.namedColors" }
|
|
12
|
+
/// The id of the ``Dock/Buttons/greetingFont(action:title:icon:isEnabled:isVisible:)`` button.
|
|
13
|
+
static var greetingFont: EditorComponentID { "ly.img.component.dock.button.postcard.greetingFont" }
|
|
14
|
+
/// The id of the ``Dock/Buttons/greetingSize(action:title:icon:isEnabled:isVisible:)`` button.
|
|
15
|
+
static var greetingSize: EditorComponentID { "ly.img.component.dock.button.postcard.greetingSize" }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// MARK: - Dock Buttons
|
|
19
|
+
|
|
20
|
+
extension Dock.Buttons {
|
|
21
|
+
/// Creates a dock button that opens the selection colors sheet.
|
|
22
|
+
static func designColors(
|
|
23
|
+
action: @escaping Dock.Context.To<Void> = {
|
|
24
|
+
$0.eventHandler.send(.openSheet(type: .designColors()))
|
|
25
|
+
},
|
|
26
|
+
@ViewBuilder title: @escaping Dock.Context.To<some View> = { _ in
|
|
27
|
+
Text(.imgly.localized("ly_img_editor_dock_button_colors"))
|
|
28
|
+
},
|
|
29
|
+
@ViewBuilder icon: @escaping Dock.Context.To<some View> = { _ in SelectionColorsIcon() },
|
|
30
|
+
isEnabled: @escaping Dock.Context.To<Bool> = { _ in true },
|
|
31
|
+
isVisible: @escaping Dock.Context.To<Bool> = {
|
|
32
|
+
try $0.engine.scene.getPages().first == $0.engine.scene.getCurrentPage()
|
|
33
|
+
},
|
|
34
|
+
) -> some Dock.Item {
|
|
35
|
+
Dock.Button(id: ID.designColors, action: action, label: { context in
|
|
36
|
+
let title = try title(context)
|
|
37
|
+
let icon = try icon(context)
|
|
38
|
+
Label { title } icon: { icon }
|
|
39
|
+
}, isEnabled: isEnabled, isVisible: isVisible)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/// Creates a dock button that opens the greeting color sheet.
|
|
43
|
+
static func greetingColors(
|
|
44
|
+
action: @escaping Dock.Context.To<Void> = {
|
|
45
|
+
guard let id = $0.engine.block.find(byName: "Greeting").first else { return }
|
|
46
|
+
$0.eventHandler.send(.openSheet(type: .greetingColors(id: id, colorPalette: [
|
|
47
|
+
.init("Governor Bay", .imgly.hex("#263BAA")!),
|
|
48
|
+
.init("Resolution Blue", .imgly.hex("#002094")!),
|
|
49
|
+
.init("Stratos", .imgly.hex("#001346")!),
|
|
50
|
+
.init("Blue Charcoal", .imgly.hex("#000514")!),
|
|
51
|
+
.init("Black", .imgly.hex("#000000")!),
|
|
52
|
+
.init("Dove Gray", .imgly.hex("#696969")!),
|
|
53
|
+
.init("Dusty Gray", .imgly.hex("#999999")!),
|
|
54
|
+
])))
|
|
55
|
+
},
|
|
56
|
+
@ViewBuilder title: @escaping Dock.Context.To<some View> = { _ in
|
|
57
|
+
Text(.imgly.localized("ly_img_editor_dock_button_colors"))
|
|
58
|
+
},
|
|
59
|
+
@ViewBuilder icon: @escaping Dock.Context.To<some View> = {
|
|
60
|
+
let id = $0.engine.block.find(byName: "Greeting").first
|
|
61
|
+
return FillColorIcon()
|
|
62
|
+
.imgly.selection(id)
|
|
63
|
+
},
|
|
64
|
+
isEnabled: @escaping Dock.Context.To<Bool> = { _ in true },
|
|
65
|
+
isVisible: @escaping Dock.Context.To<Bool> = {
|
|
66
|
+
try $0.engine.scene.getPages().last == $0.engine.scene.getCurrentPage()
|
|
67
|
+
},
|
|
68
|
+
) -> some Dock.Item {
|
|
69
|
+
Dock.Button(id: ID.greetingColors, action: action, label: { context in
|
|
70
|
+
let title = try title(context)
|
|
71
|
+
let icon = try icon(context)
|
|
72
|
+
Label { title } icon: { icon }
|
|
73
|
+
}, isEnabled: isEnabled, isVisible: isVisible)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// Creates a dock button that opens the greeting font sheet.
|
|
77
|
+
static func greetingFont(
|
|
78
|
+
action: @escaping Dock.Context.To<Void> = {
|
|
79
|
+
guard let id = $0.engine.block.find(byName: "Greeting").first else { return }
|
|
80
|
+
$0.eventHandler.send(.openSheet(type: .greetingFont(id: id, fontFamilies: [
|
|
81
|
+
"Caveat", "Amatic SC", "Courier Prime", "Archivo", "Roboto", "Parisienne",
|
|
82
|
+
])))
|
|
83
|
+
},
|
|
84
|
+
@ViewBuilder title: @escaping Dock.Context.To<some View> = { _ in
|
|
85
|
+
Text(.imgly.localized("ly_img_editor_dock_button_font"))
|
|
86
|
+
},
|
|
87
|
+
@ViewBuilder icon: @escaping Dock.Context.To<some View> = {
|
|
88
|
+
let id = $0.engine.block.find(byName: "Greeting").first
|
|
89
|
+
return FontIcon()
|
|
90
|
+
.imgly.selection(id)
|
|
91
|
+
},
|
|
92
|
+
isEnabled: @escaping Dock.Context.To<Bool> = { _ in true },
|
|
93
|
+
isVisible: @escaping Dock.Context.To<Bool> = {
|
|
94
|
+
try $0.engine.scene.getPages().last == $0.engine.scene.getCurrentPage()
|
|
95
|
+
},
|
|
96
|
+
) -> some Dock.Item {
|
|
97
|
+
Dock.Button(id: ID.greetingFont, action: action, label: { context in
|
|
98
|
+
let title = try title(context)
|
|
99
|
+
let icon = try icon(context)
|
|
100
|
+
Label { title } icon: { icon }
|
|
101
|
+
}, isEnabled: isEnabled, isVisible: isVisible)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/// Creates a dock button that opens the greeting font size sheet.
|
|
105
|
+
static func greetingSize(
|
|
106
|
+
action: @escaping Dock.Context.To<Void> = {
|
|
107
|
+
guard let id = $0.engine.block.find(byName: "Greeting").first else { return }
|
|
108
|
+
$0.eventHandler.send(.openSheet(type: .greetingSize(id: id)))
|
|
109
|
+
},
|
|
110
|
+
@ViewBuilder title: @escaping Dock.Context.To<some View> = { _ in
|
|
111
|
+
Text(.imgly.localized("ly_img_editor_dock_button_size"))
|
|
112
|
+
},
|
|
113
|
+
@ViewBuilder icon: @escaping Dock.Context.To<some View> = { context in
|
|
114
|
+
let id = context.engine.block.find(byName: "Greeting").first
|
|
115
|
+
return FontSizeIcon()
|
|
116
|
+
.imgly.selection(id)
|
|
117
|
+
},
|
|
118
|
+
isEnabled: @escaping Dock.Context.To<Bool> = { _ in true },
|
|
119
|
+
isVisible: @escaping Dock.Context.To<Bool> = {
|
|
120
|
+
try $0.engine.scene.getPages().last == $0.engine.scene.getCurrentPage()
|
|
121
|
+
},
|
|
122
|
+
) -> some Dock.Item {
|
|
123
|
+
Dock.Button(id: ID.greetingSize, action: action, label: { context in
|
|
124
|
+
let title = try title(context)
|
|
125
|
+
let icon = try icon(context)
|
|
126
|
+
Label { title } icon: { icon }
|
|
127
|
+
}, isEnabled: isEnabled, isVisible: isVisible)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
|
|
3
|
+
// MARK: - Inspector Bar
|
|
4
|
+
|
|
5
|
+
extension PostcardEditorConfiguration {
|
|
6
|
+
/// The default inspector bar configuration.
|
|
7
|
+
static var defaultInspectorBar: InspectorBar.Configuration {
|
|
8
|
+
InspectorBar.Configuration { builder in
|
|
9
|
+
// highlight-starter-kit-inspector-bar
|
|
10
|
+
builder.items { _ in
|
|
11
|
+
InspectorBar.Buttons.replace()
|
|
12
|
+
|
|
13
|
+
InspectorBar.Buttons.editText()
|
|
14
|
+
InspectorBar.Buttons.formatText()
|
|
15
|
+
InspectorBar.Buttons.fillStroke()
|
|
16
|
+
InspectorBar.Buttons.textBackground()
|
|
17
|
+
InspectorBar.Buttons.crop()
|
|
18
|
+
|
|
19
|
+
InspectorBar.Buttons.adjustments()
|
|
20
|
+
InspectorBar.Buttons.filter()
|
|
21
|
+
InspectorBar.Buttons.effect()
|
|
22
|
+
InspectorBar.Buttons.blur()
|
|
23
|
+
InspectorBar.Buttons.shape()
|
|
24
|
+
|
|
25
|
+
InspectorBar.Buttons.selectGroup()
|
|
26
|
+
InspectorBar.Buttons.enterGroup()
|
|
27
|
+
|
|
28
|
+
InspectorBar.Buttons.layer()
|
|
29
|
+
InspectorBar.Buttons.duplicate()
|
|
30
|
+
InspectorBar.Buttons.delete()
|
|
31
|
+
}
|
|
32
|
+
// highlight-starter-kit-inspector-bar
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
|
|
3
|
+
// MARK: - Navigation Bar
|
|
4
|
+
|
|
5
|
+
extension PostcardEditorConfiguration {
|
|
6
|
+
/// The default navigation bar configuration.
|
|
7
|
+
static var defaultNavigationBar: NavigationBar.Configuration {
|
|
8
|
+
NavigationBar.Configuration { builder in
|
|
9
|
+
// highlight-starter-kit-navigation-bar
|
|
10
|
+
builder.items { _ in
|
|
11
|
+
NavigationBar.ItemGroup(placement: .topBarLeading) {
|
|
12
|
+
NavigationBar.Buttons.closeEditor()
|
|
13
|
+
NavigationBar.Buttons.previousPage(
|
|
14
|
+
label: { _ in NavigationLabel(
|
|
15
|
+
.imgly.localized("ly_img_editor_navigation_bar_button_design"),
|
|
16
|
+
direction: .backward,
|
|
17
|
+
) },
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
NavigationBar.ItemGroup(placement: .principal) {
|
|
21
|
+
NavigationBar.Buttons.undo()
|
|
22
|
+
NavigationBar.Buttons.redo()
|
|
23
|
+
NavigationBar.Buttons.togglePreviewMode()
|
|
24
|
+
}
|
|
25
|
+
NavigationBar.ItemGroup(placement: .topBarTrailing) {
|
|
26
|
+
NavigationBar.Buttons.nextPage(
|
|
27
|
+
label: { _ in NavigationLabel(
|
|
28
|
+
.imgly.localized("ly_img_editor_navigation_bar_button_write"),
|
|
29
|
+
direction: .forward,
|
|
30
|
+
) },
|
|
31
|
+
)
|
|
32
|
+
NavigationBar.Buttons.export()
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// highlight-starter-kit-navigation-bar
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
import IMGLYEngine
|
|
3
|
+
import SwiftUI
|
|
4
|
+
|
|
5
|
+
// CE.SDK Starter Kit: Video Editor
|
|
6
|
+
//
|
|
7
|
+
// This starter kit provides a complete, production-ready Video Editor configuration
|
|
8
|
+
// with all configuration code inline and fully documented. Copy this file into your
|
|
9
|
+
// project and customize it to match your needs.
|
|
10
|
+
|
|
11
|
+
// MARK: - Configuration
|
|
12
|
+
|
|
13
|
+
public final class VideoEditorConfiguration: EditorConfiguration {
|
|
14
|
+
// MARK: - EditorConfiguration — Settings
|
|
15
|
+
|
|
16
|
+
/// The zoom padding for the canvas.
|
|
17
|
+
override public var zoomPadding: CGFloat? { 1 }
|
|
18
|
+
|
|
19
|
+
/// The asset library configuration.
|
|
20
|
+
///
|
|
21
|
+
/// Includes video and audio categories for the video editor.
|
|
22
|
+
override public var assetLibrary: AssetLibraryConfiguration? {
|
|
23
|
+
AssetLibraryConfiguration { builder in
|
|
24
|
+
builder.includeAVResources = true
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// MARK: - EditorConfiguration — Callbacks
|
|
29
|
+
|
|
30
|
+
/// The `onCreate` handler.
|
|
31
|
+
override public var onCreate: OnCreate.Handler? { Self.defaultOnCreateHandler }
|
|
32
|
+
|
|
33
|
+
/// The export handler.
|
|
34
|
+
///
|
|
35
|
+
/// Default: Exports the current page as MP4 and opens the system share sheet.
|
|
36
|
+
override public var onExport: OnExport.Handler? { Self.defaultOnExportHandler }
|
|
37
|
+
|
|
38
|
+
// MARK: - EditorConfiguration — UI Components
|
|
39
|
+
|
|
40
|
+
/// The navigation bar configuration.
|
|
41
|
+
override public var navigationBar: NavigationBar.Configuration? { Self.defaultNavigationBar }
|
|
42
|
+
|
|
43
|
+
/// The dock configuration.
|
|
44
|
+
override public var dock: Dock.Configuration? { Self.defaultDock }
|
|
45
|
+
|
|
46
|
+
/// The inspector bar configuration.
|
|
47
|
+
override public var inspectorBar: InspectorBar.Configuration? { Self.defaultInspectorBar }
|
|
48
|
+
|
|
49
|
+
/// The canvas menu configuration.
|
|
50
|
+
override public var canvasMenu: CanvasMenu.Configuration? { Self.defaultCanvasMenu }
|
|
51
|
+
|
|
52
|
+
/// The bottom panel configuration.
|
|
53
|
+
override public var bottomPanel: BottomPanel.Configuration? { Self.defaultBottomPanel }
|
|
54
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
import IMGLYEngine
|
|
3
|
+
import SwiftUI
|
|
4
|
+
|
|
5
|
+
// MARK: - Starter Kit View
|
|
6
|
+
|
|
7
|
+
struct VideoEditorStarterKit: View {
|
|
8
|
+
// Provide `EngineSettings` with your license and an optional userId.
|
|
9
|
+
let settings = EngineSettings(
|
|
10
|
+
license: secrets.licenseKey, // Use nil for evaluation mode with watermark
|
|
11
|
+
userID: "<your unique user id>",
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
// highlight-starter-kit-view
|
|
15
|
+
var body: some View {
|
|
16
|
+
// highlight-starter-kit-composable
|
|
17
|
+
Editor(settings)
|
|
18
|
+
.imgly.configuration {
|
|
19
|
+
VideoEditorConfiguration()
|
|
20
|
+
}
|
|
21
|
+
// highlight-starter-kit-composable
|
|
22
|
+
}
|
|
23
|
+
// highlight-starter-kit-view
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// MARK: - Preview
|
|
27
|
+
|
|
28
|
+
#Preview {
|
|
29
|
+
VideoEditorStarterKit()
|
|
30
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
import IMGLYEngine
|
|
3
|
+
import UIKit
|
|
4
|
+
|
|
5
|
+
// MARK: - Default OnCreate
|
|
6
|
+
|
|
7
|
+
public extension VideoEditorConfiguration {
|
|
8
|
+
/// The default `onCreate` handler.
|
|
9
|
+
internal static var defaultOnCreateHandler: OnCreate.Handler {
|
|
10
|
+
{ engine, _ in
|
|
11
|
+
try await defaultOnCreate()(engine)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/// Default video editor specific `OnCreate.Callback` implementation with solution specific settings, scene
|
|
16
|
+
/// and editor creation setup.
|
|
17
|
+
/// - Parameters:
|
|
18
|
+
/// - preCreateScene: Callback to do any pre scene loading tasks such as applying settings.
|
|
19
|
+
/// Defaults to `VideoEditorConfiguration.defaultPreCreateScene`.
|
|
20
|
+
/// - createScene: Callback to load/create the scene and load asset sources. Defaults to
|
|
21
|
+
/// `VideoEditorConfiguration.defaultCreateScene`.
|
|
22
|
+
/// - loadAssetSources: Callback to load any asset sources. Defaults to
|
|
23
|
+
/// `VideoEditorConfiguration.defaultLoadAssetSources`.
|
|
24
|
+
/// - postCreateScene: Callback to do any post scene loading tasks. Defaults to
|
|
25
|
+
/// `VideoEditorConfiguration.defaultPostCreateScene`.
|
|
26
|
+
/// - Returns: A composed `OnCreate.Callback`that sequentially executes all three initialization phases.
|
|
27
|
+
static func defaultOnCreate(
|
|
28
|
+
preCreateScene: @escaping OnCreate.Callback = defaultPreCreateScene,
|
|
29
|
+
createScene: @escaping OnCreate.Callback = defaultCreateScene,
|
|
30
|
+
loadAssetSources: @escaping OnCreate.Callback = defaultLoadAssetSources,
|
|
31
|
+
postCreateScene: @escaping OnCreate.Callback = defaultPostCreateScene,
|
|
32
|
+
) -> OnCreate.Callback {
|
|
33
|
+
{ engine in
|
|
34
|
+
try await preCreateScene(engine)
|
|
35
|
+
try await createScene(engine)
|
|
36
|
+
try await loadAssetSources(engine)
|
|
37
|
+
try await postCreateScene(engine)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// Configures engine settings before scene loading.
|
|
42
|
+
///
|
|
43
|
+
/// Sets editor role, touch gestures, camera clamping, gizmo handles, and global scopes.
|
|
44
|
+
static let defaultPreCreateScene: OnCreate.Callback = { engine in
|
|
45
|
+
try engine.editor.setRole("Adopter")
|
|
46
|
+
try engine.editor.setSettingEnum("camera/clamping/overshootMode", value: "Center")
|
|
47
|
+
|
|
48
|
+
let highlightColor: IMGLYEngine.Color = try engine.editor.getSettingColor("highlightColor")
|
|
49
|
+
try engine.editor.setSettingColor("placeholderHighlightColor", color: highlightColor)
|
|
50
|
+
|
|
51
|
+
try engine.editor.setSettingBool("touch/singlePointPanning", value: false)
|
|
52
|
+
try engine.editor.setSettingBool("touch/dragStartCanSelect", value: false)
|
|
53
|
+
try engine.editor.setSettingEnum("touch/pinchAction", value: "Scale")
|
|
54
|
+
|
|
55
|
+
try engine.editor.setSettingBool("controlGizmo/showMoveHandles", value: false)
|
|
56
|
+
try engine.editor.setSettingBool("controlGizmo/showRotateHandles", value: false)
|
|
57
|
+
try engine.editor.setSettingBool("controlGizmo/showScaleHandles", value: false)
|
|
58
|
+
|
|
59
|
+
try engine.editor.setSettingColor(
|
|
60
|
+
"page/innerBorderColor",
|
|
61
|
+
color: .init(cgColor: UIColor.lightGray.withAlphaComponent(0.5).cgColor)!,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
try ([
|
|
65
|
+
"appearance/adjustments", "appearance/filter", "appearance/effect",
|
|
66
|
+
"appearance/blur", "appearance/shadow",
|
|
67
|
+
"editor/select",
|
|
68
|
+
"fill/change", "fill/changeType",
|
|
69
|
+
"layer/crop", "layer/move", "layer/resize", "layer/rotate", "layer/flip",
|
|
70
|
+
"layer/opacity", "layer/blendMode", "layer/visibility", "layer/clipping",
|
|
71
|
+
"lifecycle/destroy", "lifecycle/duplicate",
|
|
72
|
+
"stroke/change", "shape/change",
|
|
73
|
+
"text/edit", "text/character",
|
|
74
|
+
]).forEach { scope in
|
|
75
|
+
try engine.editor.setGlobalScope(key: scope, value: .defer)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/// Loads the built-in empty video scene.
|
|
80
|
+
static let defaultCreateScene: OnCreate.Callback = { engine in
|
|
81
|
+
// highlight-starter-kit-on-create-scene
|
|
82
|
+
let sceneURL = Bundle(for: VideoEditorConfiguration.self).url(forResource: "video-empty", withExtension: "scene")!
|
|
83
|
+
try await engine.scene.load(from: sceneURL)
|
|
84
|
+
// highlight-starter-kit-on-create-scene
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/// Registers all default and demo asset sources, plus text and photo roll sources.
|
|
88
|
+
static let defaultLoadAssetSources: OnCreate.Callback = { engine in
|
|
89
|
+
// highlight-starter-kit-on-load-asset-sources
|
|
90
|
+
let assetSources: [String: URL] = [
|
|
91
|
+
Engine.DefaultAssetSource.sticker.rawValue: Engine.assetBaseURL,
|
|
92
|
+
Engine.DefaultAssetSource.vectorPath.rawValue: Engine.assetBaseURL,
|
|
93
|
+
Engine.DefaultAssetSource.filterLut.rawValue: Engine.assetBaseURL,
|
|
94
|
+
Engine.DefaultAssetSource.filterDuotone.rawValue: Engine.assetBaseURL,
|
|
95
|
+
Engine.DefaultAssetSource.colorsDefaultPalette.rawValue: Engine.assetBaseURL,
|
|
96
|
+
Engine.DefaultAssetSource.effect.rawValue: Engine.assetBaseURL,
|
|
97
|
+
Engine.DefaultAssetSource.blur.rawValue: Engine.assetBaseURL,
|
|
98
|
+
Engine.DefaultAssetSource.typeface.rawValue: Engine.assetBaseURL,
|
|
99
|
+
Engine.DefaultAssetSource.cropPresets.rawValue: Engine.assetBaseURL,
|
|
100
|
+
Engine.DefaultAssetSource.pagePresets.rawValue: Engine.assetBaseURL,
|
|
101
|
+
|
|
102
|
+
Engine.DemoAssetSource.image.rawValue: Engine.assetBaseURL,
|
|
103
|
+
Engine.DemoAssetSource.video.rawValue: Engine.assetBaseURL,
|
|
104
|
+
Engine.DemoAssetSource.audio.rawValue: Engine.assetBaseURL,
|
|
105
|
+
Engine.DemoAssetSource.textComponents.rawValue: Engine.assetBaseURL,
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
try await withThrowingTaskGroup(of: Void.self) { group in
|
|
109
|
+
for assetSource in assetSources {
|
|
110
|
+
group.addTask {
|
|
111
|
+
try await engine.populateAssetSource(id: assetSource.key, baseURL: assetSource.value)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
try await group.waitForAll()
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let localAssetSources: [Engine.DemoAssetSource] = [
|
|
118
|
+
.imageUpload,
|
|
119
|
+
.audioUpload,
|
|
120
|
+
.videoUpload,
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
for localAssetSource in localAssetSources {
|
|
124
|
+
try engine.asset.addLocalSource(
|
|
125
|
+
sourceID: localAssetSource.rawValue,
|
|
126
|
+
supportedMimeTypes: localAssetSource.mimeTypes,
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
try await engine.asset.addSource(TextAssetSource(engine: engine))
|
|
131
|
+
try engine.asset.addSource(PhotoRollAssetSource(engine: engine))
|
|
132
|
+
// highlight-starter-kit-on-load-asset-sources
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/// No additional post-scene configuration needed for video editor.
|
|
136
|
+
static let defaultPostCreateScene: OnCreate.Callback = { _ in }
|
|
137
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import IMGLYEditor
|
|
3
|
+
import IMGLYEngine
|
|
4
|
+
|
|
5
|
+
// MARK: - Default OnExport
|
|
6
|
+
|
|
7
|
+
extension VideoEditorConfiguration {
|
|
8
|
+
/// The default export handler.
|
|
9
|
+
///
|
|
10
|
+
/// Exports the current page as MP4 and opens the system share sheet.
|
|
11
|
+
static var defaultOnExportHandler: OnExport.Handler {
|
|
12
|
+
{ engine, eventHandler, _ in
|
|
13
|
+
// highlight-starter-kit-on-export
|
|
14
|
+
guard let page = try engine.scene.getCurrentPage() else {
|
|
15
|
+
throw EditorError("No page was found.")
|
|
16
|
+
}
|
|
17
|
+
eventHandler.send(.exportProgress(.relative(0)))
|
|
18
|
+
let mimeType: MIMEType = .mp4
|
|
19
|
+
let stream = try await engine.block.exportVideo(page, mimeType: mimeType) { _ in }
|
|
20
|
+
|
|
21
|
+
var lastReportedProgress = 0
|
|
22
|
+
for try await export in stream {
|
|
23
|
+
try Task.checkCancellation()
|
|
24
|
+
switch export {
|
|
25
|
+
case let .progress(_, encodedFrames, totalFrames):
|
|
26
|
+
let progress = Int((Float(encodedFrames) / Float(totalFrames)) * 100)
|
|
27
|
+
if progress > lastReportedProgress {
|
|
28
|
+
lastReportedProgress = progress
|
|
29
|
+
eventHandler.send(.exportProgress(.relative(Float(progress) / 100)))
|
|
30
|
+
}
|
|
31
|
+
case let .finished(video: videoData):
|
|
32
|
+
let url = FileManager.default.temporaryDirectory.appendingPathComponent(
|
|
33
|
+
"Export",
|
|
34
|
+
conformingTo: mimeType.uniformType,
|
|
35
|
+
)
|
|
36
|
+
try videoData.write(to: url, options: [.atomic])
|
|
37
|
+
eventHandler.send(.exportCompleted { eventHandler.send(.shareFile(url)) })
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
try Task.checkCancellation()
|
|
42
|
+
throw EditorError("Failed to export the content.")
|
|
43
|
+
// highlight-starter-kit-on-export
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
|
|
3
|
+
// MARK: - Bottom Panel
|
|
4
|
+
|
|
5
|
+
extension VideoEditorConfiguration {
|
|
6
|
+
/// The default bottom panel configuration.
|
|
7
|
+
static var defaultBottomPanel: BottomPanel.Configuration {
|
|
8
|
+
BottomPanel.Configuration { builder in
|
|
9
|
+
// highlight-starter-kit-bottom-panel
|
|
10
|
+
builder.content { context in
|
|
11
|
+
DefaultTimelineComponent(context: context)
|
|
12
|
+
}
|
|
13
|
+
// highlight-starter-kit-bottom-panel
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
|
|
3
|
+
// MARK: - Canvas Menu
|
|
4
|
+
|
|
5
|
+
extension VideoEditorConfiguration {
|
|
6
|
+
/// The default canvas menu configuration.
|
|
7
|
+
static var defaultCanvasMenu: CanvasMenu.Configuration {
|
|
8
|
+
CanvasMenu.Configuration { builder in
|
|
9
|
+
// highlight-starter-kit-canvas-menu
|
|
10
|
+
builder.items { _ in
|
|
11
|
+
CanvasMenu.Buttons.selectGroup()
|
|
12
|
+
CanvasMenu.Divider()
|
|
13
|
+
CanvasMenu.Buttons.bringForward()
|
|
14
|
+
CanvasMenu.Buttons.sendBackward()
|
|
15
|
+
CanvasMenu.Divider()
|
|
16
|
+
CanvasMenu.Buttons.duplicate()
|
|
17
|
+
CanvasMenu.Buttons.delete()
|
|
18
|
+
}
|
|
19
|
+
// highlight-starter-kit-canvas-menu
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
import SwiftUI
|
|
3
|
+
|
|
4
|
+
// MARK: - Dock
|
|
5
|
+
|
|
6
|
+
extension VideoEditorConfiguration {
|
|
7
|
+
/// The default dock configuration.
|
|
8
|
+
static var defaultDock: Dock.Configuration {
|
|
9
|
+
Dock.Configuration { builder in
|
|
10
|
+
// highlight-starter-kit-dock
|
|
11
|
+
builder.items { _ in
|
|
12
|
+
Dock.Buttons.photoRoll(
|
|
13
|
+
action: { $0.eventHandler.send(.addFromPhotoRoll(addToBackgroundTrack: true)) },
|
|
14
|
+
icon: { _ in Image.imgly.addPhotoRollBackground },
|
|
15
|
+
) // Device photos and videos
|
|
16
|
+
// highlight-starter-kit-imgly-camera
|
|
17
|
+
Dock.Buttons.imglyCamera(icon: { _ in Image.imgly.addCameraBackground }) // Camera capture
|
|
18
|
+
// highlight-starter-kit-imgly-camera
|
|
19
|
+
Dock.Buttons.overlaysLibrary() // Video overlays
|
|
20
|
+
Dock.Buttons.textLibrary() // Text tools
|
|
21
|
+
Dock.Buttons.stickersAndShapesLibrary() // Stickers and shapes
|
|
22
|
+
Dock.Buttons.audioLibrary() // Audio tracks
|
|
23
|
+
Dock.Buttons.voiceover() // Voice recording
|
|
24
|
+
Dock.Buttons.reorder() // Clip reordering
|
|
25
|
+
Dock.Buttons.resize() // Aspect ratio and canvas size
|
|
26
|
+
}
|
|
27
|
+
// highlight-starter-kit-dock
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
|
|
3
|
+
// MARK: - Inspector Bar
|
|
4
|
+
|
|
5
|
+
extension VideoEditorConfiguration {
|
|
6
|
+
/// The default inspector bar configuration.
|
|
7
|
+
static var defaultInspectorBar: InspectorBar.Configuration {
|
|
8
|
+
InspectorBar.Configuration { builder in
|
|
9
|
+
// highlight-starter-kit-inspector-bar
|
|
10
|
+
builder.items { _ in
|
|
11
|
+
InspectorBar.Buttons.replace()
|
|
12
|
+
|
|
13
|
+
InspectorBar.Buttons.editText()
|
|
14
|
+
InspectorBar.Buttons.formatText()
|
|
15
|
+
InspectorBar.Buttons.fillStroke()
|
|
16
|
+
InspectorBar.Buttons.textBackground()
|
|
17
|
+
InspectorBar.Buttons.addVoiceoverRecording()
|
|
18
|
+
InspectorBar.Buttons.volume()
|
|
19
|
+
InspectorBar.Buttons.clipSpeed()
|
|
20
|
+
InspectorBar.Buttons.crop()
|
|
21
|
+
|
|
22
|
+
InspectorBar.Buttons.adjustments()
|
|
23
|
+
InspectorBar.Buttons.filter()
|
|
24
|
+
InspectorBar.Buttons.effect()
|
|
25
|
+
InspectorBar.Buttons.blur()
|
|
26
|
+
InspectorBar.Buttons.animation()
|
|
27
|
+
InspectorBar.Buttons.shape()
|
|
28
|
+
|
|
29
|
+
InspectorBar.Buttons.selectGroup()
|
|
30
|
+
InspectorBar.Buttons.enterGroup()
|
|
31
|
+
|
|
32
|
+
InspectorBar.Buttons.layer()
|
|
33
|
+
InspectorBar.Buttons.split()
|
|
34
|
+
InspectorBar.Buttons.moveAsClip()
|
|
35
|
+
InspectorBar.Buttons.moveAsOverlay()
|
|
36
|
+
InspectorBar.Buttons.reorder()
|
|
37
|
+
InspectorBar.Buttons.duplicate()
|
|
38
|
+
InspectorBar.Buttons.delete()
|
|
39
|
+
}
|
|
40
|
+
// highlight-starter-kit-inspector-bar
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import IMGLYEditor
|
|
2
|
+
|
|
3
|
+
// MARK: - Navigation Bar
|
|
4
|
+
|
|
5
|
+
extension VideoEditorConfiguration {
|
|
6
|
+
/// The default navigation bar configuration.
|
|
7
|
+
static var defaultNavigationBar: NavigationBar.Configuration {
|
|
8
|
+
NavigationBar.Configuration { builder in
|
|
9
|
+
// highlight-starter-kit-navigation-bar
|
|
10
|
+
builder.items { _ in
|
|
11
|
+
NavigationBar.ItemGroup(placement: .topBarLeading) {
|
|
12
|
+
NavigationBar.Buttons.closeEditor()
|
|
13
|
+
}
|
|
14
|
+
NavigationBar.ItemGroup(placement: .topBarTrailing) {
|
|
15
|
+
NavigationBar.Buttons.undo()
|
|
16
|
+
NavigationBar.Buttons.redo()
|
|
17
|
+
NavigationBar.Buttons.export(
|
|
18
|
+
isEnabled: {
|
|
19
|
+
guard !$0.state.isCreating, !$0.state.isExporting,
|
|
20
|
+
let engine = $0.engine,
|
|
21
|
+
let scene = try engine.scene.get() else {
|
|
22
|
+
return false
|
|
23
|
+
}
|
|
24
|
+
return try engine.block.getDuration(scene) > 0
|
|
25
|
+
},
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// highlight-starter-kit-navigation-bar
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|