@imgly/editor-react-native 1.73.0 → 1.74.0
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/IMGLYEditorModule.podspec +0 -21
- package/android/build.gradle +1 -5
- 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
package/android/src/main/kotlin/ly/img/editor/configuration/postcard/component/NavigationBar.kt
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
@file:Suppress("UnusedReceiverParameter", "UnusedFlow")
|
|
2
|
+
|
|
3
|
+
package ly.img.editor.configuration.postcard.component
|
|
4
|
+
|
|
5
|
+
import androidx.compose.runtime.Composable
|
|
6
|
+
import androidx.compose.runtime.collectAsState
|
|
7
|
+
import androidx.compose.runtime.getValue
|
|
8
|
+
import androidx.compose.runtime.remember
|
|
9
|
+
import androidx.compose.ui.Alignment
|
|
10
|
+
import androidx.compose.ui.res.stringResource
|
|
11
|
+
import kotlinx.coroutines.flow.emptyFlow
|
|
12
|
+
import kotlinx.coroutines.flow.map
|
|
13
|
+
import ly.img.editor.configuration.postcard.PostcardConfigurationBuilder
|
|
14
|
+
import ly.img.editor.configuration.postcard.ext.getCurrentPageIndex
|
|
15
|
+
import ly.img.editor.core.R
|
|
16
|
+
import ly.img.editor.core.component.EditorTrigger
|
|
17
|
+
import ly.img.editor.core.component.NavigationBar
|
|
18
|
+
import ly.img.editor.core.component.remember
|
|
19
|
+
import ly.img.editor.core.component.rememberCloseEditor
|
|
20
|
+
import ly.img.editor.core.component.rememberExport
|
|
21
|
+
import ly.img.editor.core.component.rememberNextPage
|
|
22
|
+
import ly.img.editor.core.component.rememberPreviousPage
|
|
23
|
+
import ly.img.editor.core.component.rememberRedo
|
|
24
|
+
import ly.img.editor.core.component.rememberTogglePreviewMode
|
|
25
|
+
import ly.img.editor.core.component.rememberUndo
|
|
26
|
+
import ly.img.engine.DesignBlockType
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The configuration of the component that is displayed as horizontal list of items at the top of the editor.
|
|
30
|
+
*/
|
|
31
|
+
@Composable
|
|
32
|
+
fun PostcardConfigurationBuilder.rememberNavigationBar() = NavigationBar.remember {
|
|
33
|
+
scope = {
|
|
34
|
+
val activeSceneTrigger by EditorTrigger.remember {
|
|
35
|
+
editorContext.engine.scene.onActiveChanged()
|
|
36
|
+
}
|
|
37
|
+
val historyTrigger by EditorTrigger.remember(activeSceneTrigger) {
|
|
38
|
+
editorContext.engine.editor.onHistoryUpdated()
|
|
39
|
+
}
|
|
40
|
+
val pageIndex by remember(this, activeSceneTrigger) {
|
|
41
|
+
if (editorContext.engine.scene.get() == null) return@remember emptyFlow()
|
|
42
|
+
val stack = editorContext.engine.block.findByType(DesignBlockType.Stack).first()
|
|
43
|
+
editorContext.engine.event.subscribe(listOf(stack))
|
|
44
|
+
.map { editorContext.engine.getCurrentPageIndex() }
|
|
45
|
+
}.collectAsState(initial = 0)
|
|
46
|
+
// Update NavigationBar whenever the active scene, editor history or current page index changes
|
|
47
|
+
remember(this, pageIndex, historyTrigger) {
|
|
48
|
+
NavigationBar.Scope(parentScope = this)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
listBuilder = {
|
|
52
|
+
NavigationBar.ListBuilder.remember {
|
|
53
|
+
aligned(alignment = Alignment.Start) {
|
|
54
|
+
add { NavigationBar.Button.rememberCloseEditor() }
|
|
55
|
+
add {
|
|
56
|
+
NavigationBar.Button.rememberPreviousPage {
|
|
57
|
+
textString = { stringResource(R.string.ly_img_editor_navigation_bar_button_design) }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
aligned(alignment = Alignment.CenterHorizontally) {
|
|
62
|
+
add { NavigationBar.Button.rememberUndo() }
|
|
63
|
+
add { NavigationBar.Button.rememberRedo() }
|
|
64
|
+
add { NavigationBar.Button.rememberTogglePreviewMode() }
|
|
65
|
+
}
|
|
66
|
+
aligned(alignment = Alignment.End) {
|
|
67
|
+
add {
|
|
68
|
+
NavigationBar.Button.rememberNextPage {
|
|
69
|
+
textString = { stringResource(R.string.ly_img_editor_navigation_bar_button_write) }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
add { NavigationBar.Button.rememberExport() }
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
package ly.img.editor.configuration.postcard.component
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.Composable
|
|
4
|
+
import ly.img.editor.configuration.postcard.PostcardConfigurationBuilder
|
|
5
|
+
import ly.img.editor.core.component.EditorComponent
|
|
6
|
+
import ly.img.editor.core.component.remember
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The configuration of the component that is displayed over the editor. It is useful if you want to display a popup dialog or anything in the
|
|
10
|
+
* overlay.
|
|
11
|
+
*/
|
|
12
|
+
@Composable
|
|
13
|
+
fun PostcardConfigurationBuilder.rememberOverlay() = EditorComponent.remember {
|
|
14
|
+
decoration = { Overlay() }
|
|
15
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
package ly.img.editor.configuration.postcard.ext
|
|
2
|
+
|
|
3
|
+
import androidx.compose.ui.graphics.Color
|
|
4
|
+
import ly.img.editor.core.component.data.ConicalGradientFill
|
|
5
|
+
import ly.img.editor.core.component.data.Fill
|
|
6
|
+
import ly.img.editor.core.component.data.LinearGradientFill
|
|
7
|
+
import ly.img.editor.core.component.data.RadialGradientFill
|
|
8
|
+
import ly.img.editor.core.component.data.SolidFill
|
|
9
|
+
import ly.img.engine.ColorSpace
|
|
10
|
+
import ly.img.engine.DesignBlock
|
|
11
|
+
import ly.img.engine.DesignBlockType
|
|
12
|
+
import ly.img.engine.Engine
|
|
13
|
+
import ly.img.engine.FillType
|
|
14
|
+
import ly.img.engine.RGBAColor
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Returns current page index.
|
|
18
|
+
*/
|
|
19
|
+
internal fun Engine.getCurrentPageIndex() = scene.run { getPages().indexOf(getCurrentPage()) }
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Converts engine color into compose color.
|
|
23
|
+
*/
|
|
24
|
+
internal fun Engine.toComposeColor(color: ly.img.engine.Color): Color {
|
|
25
|
+
val rgbaEngineColor = color as? RGBAColor
|
|
26
|
+
?: editor.convertColorToColorSpace(color, ColorSpace.SRGB) as RGBAColor
|
|
27
|
+
return Color(
|
|
28
|
+
red = rgbaEngineColor.r,
|
|
29
|
+
green = rgbaEngineColor.g,
|
|
30
|
+
blue = rgbaEngineColor.b,
|
|
31
|
+
alpha = rgbaEngineColor.a,
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* An extension function that returns [FillType] of the design block.
|
|
37
|
+
*
|
|
38
|
+
* @param designBlock the design block that is queried.
|
|
39
|
+
*/
|
|
40
|
+
internal fun Engine.getFillType(designBlock: DesignBlock): FillType? = if (!block.supportsFill(designBlock)) {
|
|
41
|
+
null
|
|
42
|
+
} else {
|
|
43
|
+
FillType.Companion.get(block.getType(block.getFill(designBlock)))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* An extension function that returns [Fill] of the design block.
|
|
48
|
+
*
|
|
49
|
+
* @param designBlock the design block that is queried.
|
|
50
|
+
*/
|
|
51
|
+
internal fun Engine.getFill(designBlock: DesignBlock): Fill? = if (!block.supportsFill(designBlock)) {
|
|
52
|
+
null
|
|
53
|
+
} else {
|
|
54
|
+
when (getFillType(designBlock)) {
|
|
55
|
+
FillType.Color -> {
|
|
56
|
+
val rgbaColor = if (DesignBlockType.Companion.getOrNull(block.getType(designBlock)) == DesignBlockType.Text) {
|
|
57
|
+
block.getTextColors(designBlock).first()
|
|
58
|
+
} else {
|
|
59
|
+
block.getColor(designBlock, "fill/solid/color")
|
|
60
|
+
}
|
|
61
|
+
SolidFill(toComposeColor(rgbaColor))
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
FillType.LinearGradient -> {
|
|
65
|
+
val fill = block.getFill(designBlock)
|
|
66
|
+
LinearGradientFill(
|
|
67
|
+
startPointX = block.getFloat(fill, "fill/gradient/linear/startPointX"),
|
|
68
|
+
startPointY = block.getFloat(fill, "fill/gradient/linear/startPointY"),
|
|
69
|
+
endPointX = block.getFloat(fill, "fill/gradient/linear/endPointX"),
|
|
70
|
+
endPointY = block.getFloat(fill, "fill/gradient/linear/endPointY"),
|
|
71
|
+
colorStops = block.getGradientColorStops(fill, "fill/gradient/colors"),
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
FillType.RadialGradient -> {
|
|
76
|
+
val fill = block.getFill(designBlock)
|
|
77
|
+
RadialGradientFill(
|
|
78
|
+
centerX = block.getFloat(fill, "fill/gradient/radial/centerPointX"),
|
|
79
|
+
centerY = block.getFloat(fill, "fill/gradient/radial/centerPointY"),
|
|
80
|
+
radius = block.getFloat(fill, "fill/gradient/radial/radius"),
|
|
81
|
+
colorStops = block.getGradientColorStops(fill, "fill/gradient/colors"),
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
FillType.ConicalGradient -> {
|
|
86
|
+
val fill = block.getFill(designBlock)
|
|
87
|
+
ConicalGradientFill(
|
|
88
|
+
centerX = block.getFloat(fill, "fill/gradient/conical/centerPointX"),
|
|
89
|
+
centerY = block.getFloat(fill, "fill/gradient/conical/centerPointY"),
|
|
90
|
+
colorStops = block.getGradientColorStops(fill, "fill/gradient/colors"),
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Image fill and Video fill are not supported yet
|
|
95
|
+
else -> null
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* An extension function that returns stroke color of the design block.
|
|
101
|
+
*
|
|
102
|
+
* @param designBlock the design block that is queried.
|
|
103
|
+
*/
|
|
104
|
+
internal fun Engine.getStrokeColor(designBlock: DesignBlock): Color? {
|
|
105
|
+
if (!block.supportsStroke(designBlock)) return null
|
|
106
|
+
return toComposeColor(block.getColor(designBlock, "stroke/color"))
|
|
107
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// highlight-starter-kit-activity-full
|
|
2
|
+
package ly.img.editor.configuration.video
|
|
3
|
+
|
|
4
|
+
import android.os.Bundle
|
|
5
|
+
import androidx.activity.ComponentActivity
|
|
6
|
+
import androidx.activity.compose.setContent
|
|
7
|
+
import androidx.activity.enableEdgeToEdge
|
|
8
|
+
import ly.img.editor.Editor
|
|
9
|
+
import ly.img.editor.core.configuration.EditorConfiguration
|
|
10
|
+
import ly.img.editor.core.configuration.remember
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Encapsulated editor to be used in legacy activity navigation.
|
|
14
|
+
* Delete this file if you are using jetpack compose navigation.
|
|
15
|
+
*/
|
|
16
|
+
class EditorActivity : ComponentActivity() {
|
|
17
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
18
|
+
super.onCreate(savedInstanceState)
|
|
19
|
+
// This is required to remove the default action bar on top.
|
|
20
|
+
setTheme(android.R.style.Theme_Material_Light_NoActionBar)
|
|
21
|
+
// This is required, so that the editor is displayed full screen on relatively older devices.
|
|
22
|
+
enableEdgeToEdge()
|
|
23
|
+
setContent {
|
|
24
|
+
Editor(
|
|
25
|
+
license = null, // pass null or empty for evaluation mode with watermark
|
|
26
|
+
configuration = {
|
|
27
|
+
EditorConfiguration.remember(::VideoConfigurationBuilder)
|
|
28
|
+
},
|
|
29
|
+
onClose = {
|
|
30
|
+
// Finish the activity, potentially handle errors.
|
|
31
|
+
finish()
|
|
32
|
+
},
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// highlight-starter-kit-activity-full
|
package/android/src/main/kotlin/ly/img/editor/configuration/video/VideoConfigurationBuilder.kt
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
package ly.img.editor.configuration.video
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.Stable
|
|
4
|
+
import androidx.compose.runtime.getValue
|
|
5
|
+
import androidx.compose.runtime.setValue
|
|
6
|
+
import ly.img.editor.BasicConfigurationBuilder
|
|
7
|
+
import ly.img.editor.configuration.video.callback.onCreate
|
|
8
|
+
import ly.img.editor.configuration.video.callback.onExport
|
|
9
|
+
import ly.img.editor.configuration.video.callback.onLoaded
|
|
10
|
+
import ly.img.editor.configuration.video.component.rememberBottomPanel
|
|
11
|
+
import ly.img.editor.configuration.video.component.rememberCanvasMenu
|
|
12
|
+
import ly.img.editor.configuration.video.component.rememberDock
|
|
13
|
+
import ly.img.editor.configuration.video.component.rememberInspectorBar
|
|
14
|
+
import ly.img.editor.configuration.video.component.rememberNavigationBar
|
|
15
|
+
import ly.img.editor.configuration.video.component.rememberOverlay
|
|
16
|
+
import ly.img.editor.configuration.video.model.ExportStatus
|
|
17
|
+
import ly.img.editor.core.EditorScope
|
|
18
|
+
import ly.img.editor.core.ScopedProperty
|
|
19
|
+
import ly.img.editor.core.component.EditorComponent
|
|
20
|
+
import ly.img.editor.core.event.EditorEvent
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Configuration builder class for video editor starter kit.
|
|
24
|
+
*/
|
|
25
|
+
@Stable
|
|
26
|
+
class VideoConfigurationBuilder : BasicConfigurationBuilder() {
|
|
27
|
+
/**
|
|
28
|
+
* Current export status of the editor.
|
|
29
|
+
*/
|
|
30
|
+
var exportStatus: ExportStatus? by editorContext.mutableStateOf(
|
|
31
|
+
key = "ly.img.editor.configuration.video.state.exportStatus",
|
|
32
|
+
initial = null,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Whether export cancellation confirmation dialog should be displayed.
|
|
37
|
+
*/
|
|
38
|
+
var showCancelExportConfirmationDialog: Boolean by editorContext.mutableStateOf(
|
|
39
|
+
key = "ly.img.editor.configuration.video.state.showCancelExportConfirmationDialog",
|
|
40
|
+
initial = false,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The callback that is invoked when the editor is created.
|
|
45
|
+
* Check parent class declaration for more details.
|
|
46
|
+
*/
|
|
47
|
+
override var onCreate: (suspend EditorScope.() -> Unit)? = {
|
|
48
|
+
onCreate()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The callback that is invoked when the editor is loaded and ready to be used.
|
|
53
|
+
* Check parent class declaration for more details.
|
|
54
|
+
*/
|
|
55
|
+
override var onLoaded: (suspend EditorScope.() -> Unit)? = {
|
|
56
|
+
onLoaded()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The callback that is invoked when the export button is clicked.
|
|
61
|
+
* Check parent class declaration for more details.
|
|
62
|
+
*/
|
|
63
|
+
override var onExport: (suspend EditorScope.() -> Unit)? = {
|
|
64
|
+
onExport()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The callback that is invoked after [EditorEvent.OnClose] event is triggered or when the system back button is clicked
|
|
69
|
+
* and editor cannot handle the event internally.
|
|
70
|
+
* Check parent class declaration for more details.
|
|
71
|
+
*/
|
|
72
|
+
override var onClose: (suspend EditorScope.() -> Unit)? = {
|
|
73
|
+
showConfirmationOrCloseEditor()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The callback that is invoked after the editor captures an error.
|
|
78
|
+
* Check parent class declaration for more details.
|
|
79
|
+
*/
|
|
80
|
+
override var onError: (suspend EditorScope.(Throwable) -> Unit)? = {
|
|
81
|
+
error = it
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The configuration of the component that is displayed as horizontal list of items at the bottom of the editor.
|
|
86
|
+
* Check parent class declaration for more details.
|
|
87
|
+
*/
|
|
88
|
+
override var dock: ScopedProperty<EditorScope, EditorComponent<*>>? = {
|
|
89
|
+
rememberDock()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* The configuration of the component that is displayed as horizontal list of items at the top of the editor.
|
|
94
|
+
* Check parent class declaration for more details.
|
|
95
|
+
*/
|
|
96
|
+
override var navigationBar: ScopedProperty<EditorScope, EditorComponent<*>>? = {
|
|
97
|
+
rememberNavigationBar()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The configuration of the component that is displayed as horizontal list of items at the
|
|
102
|
+
* bottom of the editor when a design block is selected.
|
|
103
|
+
* Check parent class declaration for more details.
|
|
104
|
+
*/
|
|
105
|
+
override var inspectorBar: ScopedProperty<EditorScope, EditorComponent<*>>? = {
|
|
106
|
+
rememberInspectorBar()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The configuration of the component that is displayed as horizontal list of items next to
|
|
111
|
+
* the selected design block.
|
|
112
|
+
* Check parent class declaration for more details.
|
|
113
|
+
*/
|
|
114
|
+
override var canvasMenu: ScopedProperty<EditorScope, EditorComponent<*>>? = {
|
|
115
|
+
rememberCanvasMenu()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The configuration of the component that is displayed over the editor. It is useful if you want to display a popup dialog or anything in the
|
|
120
|
+
* overlay.
|
|
121
|
+
* Check parent class declaration for more details.
|
|
122
|
+
*/
|
|
123
|
+
override var bottomPanel: ScopedProperty<EditorScope, EditorComponent<*>>? = {
|
|
124
|
+
rememberBottomPanel()
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The configuration of the component that is displayed over the editor. It is useful if you want to display a popup dialog or anything in the
|
|
129
|
+
* overlay.
|
|
130
|
+
* Check parent class declaration for more details.
|
|
131
|
+
*/
|
|
132
|
+
override var overlay: ScopedProperty<EditorScope, EditorComponent<*>>? = {
|
|
133
|
+
rememberOverlay()
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
@file:OptIn(UnstableEditorApi::class)
|
|
2
|
+
@file:Suppress("UnusedReceiverParameter")
|
|
3
|
+
|
|
4
|
+
package ly.img.editor.configuration.video.callback
|
|
5
|
+
|
|
6
|
+
import androidx.core.net.toUri
|
|
7
|
+
import kotlinx.coroutines.coroutineScope
|
|
8
|
+
import kotlinx.coroutines.launch
|
|
9
|
+
import ly.img.editor.configuration.video.VideoConfigurationBuilder
|
|
10
|
+
import ly.img.editor.core.UnstableEditorApi
|
|
11
|
+
import ly.img.editor.core.library.data.AssetSourceType
|
|
12
|
+
import ly.img.editor.core.library.data.SystemGalleryAssetSource
|
|
13
|
+
import ly.img.editor.core.library.data.SystemGalleryPermission
|
|
14
|
+
import ly.img.editor.core.library.data.TextAssetSource
|
|
15
|
+
import ly.img.editor.core.library.data.TypefaceProvider
|
|
16
|
+
import ly.img.engine.Color
|
|
17
|
+
import ly.img.engine.DefaultAssetSource
|
|
18
|
+
import ly.img.engine.DemoAssetSource
|
|
19
|
+
import ly.img.engine.populateAssetSource
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The callback that is invoked when the editor is created.
|
|
23
|
+
*/
|
|
24
|
+
suspend fun VideoConfigurationBuilder.onCreate(
|
|
25
|
+
preCreateScene: suspend VideoConfigurationBuilder.() -> Unit = {
|
|
26
|
+
onPreCreateScene()
|
|
27
|
+
},
|
|
28
|
+
createScene: suspend VideoConfigurationBuilder.() -> Unit = {
|
|
29
|
+
onCreateScene()
|
|
30
|
+
},
|
|
31
|
+
loadAssetSources: suspend VideoConfigurationBuilder.() -> Unit = {
|
|
32
|
+
onLoadAssetSources()
|
|
33
|
+
},
|
|
34
|
+
postCreateScene: suspend VideoConfigurationBuilder.() -> Unit = {
|
|
35
|
+
onPostCreateScene()
|
|
36
|
+
},
|
|
37
|
+
finally: suspend VideoConfigurationBuilder.() -> Unit = {
|
|
38
|
+
onCreateFinally()
|
|
39
|
+
},
|
|
40
|
+
) {
|
|
41
|
+
try {
|
|
42
|
+
preCreateScene()
|
|
43
|
+
createScene()
|
|
44
|
+
loadAssetSources()
|
|
45
|
+
postCreateScene()
|
|
46
|
+
} finally {
|
|
47
|
+
finally()
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The callback that is invoked before the scene is created.
|
|
53
|
+
*/
|
|
54
|
+
fun VideoConfigurationBuilder.onPreCreateScene() {
|
|
55
|
+
showLoading = true
|
|
56
|
+
val engine = editorContext.engine
|
|
57
|
+
engine.editor.setSettingEnum(keypath = "touch/pinchAction", value = "Scale")
|
|
58
|
+
engine.editor.setSettingBoolean(
|
|
59
|
+
keypath = "controlGizmo/showRotateHandles",
|
|
60
|
+
value = false,
|
|
61
|
+
)
|
|
62
|
+
engine.editor.setSettingBoolean(
|
|
63
|
+
keypath = "controlGizmo/showScaleHandles",
|
|
64
|
+
value = false,
|
|
65
|
+
)
|
|
66
|
+
engine.editor.setSettingBoolean(keypath = "controlGizmo/showMoveHandles", value = false)
|
|
67
|
+
engine.editor.setSettingBoolean(keypath = "touch/singlePointPanning", value = false)
|
|
68
|
+
engine.editor.setSettingColor(
|
|
69
|
+
keypath = "page/innerBorderColor",
|
|
70
|
+
value = Color.fromRGBA(0.67f, 0.67f, 0.67f, 0.5f),
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The callback that is responsible for creating the scene.
|
|
76
|
+
*/
|
|
77
|
+
// highlight-starter-kit-on-create-scene
|
|
78
|
+
suspend fun VideoConfigurationBuilder.onCreateScene() {
|
|
79
|
+
getOrLoadScene(sceneUri = "file:///android_asset/scene/video.scene".toUri())
|
|
80
|
+
}
|
|
81
|
+
// highlight-starter-kit-on-create-scene
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The callback that loads all the required assets sources.
|
|
85
|
+
*/
|
|
86
|
+
// highlight-starter-kit-on-load-asset-sources
|
|
87
|
+
suspend fun VideoConfigurationBuilder.onLoadAssetSources() {
|
|
88
|
+
// Load asset sources in parallel from content.json files
|
|
89
|
+
coroutineScope {
|
|
90
|
+
listOf(
|
|
91
|
+
DefaultAssetSource.STICKER.key,
|
|
92
|
+
DefaultAssetSource.VECTOR_PATH.key,
|
|
93
|
+
DefaultAssetSource.FILTER_LUT.key,
|
|
94
|
+
DefaultAssetSource.FILTER_DUO_TONE.key,
|
|
95
|
+
DefaultAssetSource.CROP_PRESETS.key,
|
|
96
|
+
DefaultAssetSource.PAGE_PRESETS.key,
|
|
97
|
+
DefaultAssetSource.EFFECT.key,
|
|
98
|
+
DefaultAssetSource.BLUR.key,
|
|
99
|
+
DefaultAssetSource.TYPEFACE.key,
|
|
100
|
+
DemoAssetSource.IMAGE.key,
|
|
101
|
+
DemoAssetSource.AUDIO.key,
|
|
102
|
+
DemoAssetSource.VIDEO.key,
|
|
103
|
+
DemoAssetSource.TEXT_COMPONENTS.key,
|
|
104
|
+
).forEach { assetSource ->
|
|
105
|
+
launch {
|
|
106
|
+
val baseUri = editorContext.baseUri
|
|
107
|
+
editorContext.engine.populateAssetSource(
|
|
108
|
+
id = assetSource,
|
|
109
|
+
jsonUri = "$baseUri/$assetSource/content.json".toUri(),
|
|
110
|
+
replaceBaseUri = baseUri,
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Required for animations
|
|
117
|
+
editorContext.engine.block.setMetadata(
|
|
118
|
+
block = requireNotNull(editorContext.engine.scene.get()),
|
|
119
|
+
key = "ly.img.defaultAssetSourcesBaseUri",
|
|
120
|
+
value = editorContext.baseUri.toString(),
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
// Load local asset sources
|
|
124
|
+
editorContext.engine.asset.addLocalSource(
|
|
125
|
+
sourceId = DemoAssetSource.IMAGE_UPLOAD.key,
|
|
126
|
+
supportedMimeTypes = listOf(
|
|
127
|
+
"image/jpeg",
|
|
128
|
+
"image/png",
|
|
129
|
+
"image/heic",
|
|
130
|
+
"image/heif",
|
|
131
|
+
"image/svg+xml",
|
|
132
|
+
"image/gif",
|
|
133
|
+
"image/bmp",
|
|
134
|
+
),
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
editorContext.engine.asset.addLocalSource(
|
|
138
|
+
sourceId = DemoAssetSource.AUDIO_UPLOAD.key,
|
|
139
|
+
supportedMimeTypes = listOf(
|
|
140
|
+
"audio/x-m4a",
|
|
141
|
+
"audio/mp3",
|
|
142
|
+
"audio/mpeg",
|
|
143
|
+
),
|
|
144
|
+
)
|
|
145
|
+
editorContext.engine.asset.addLocalSource(
|
|
146
|
+
sourceId = DemoAssetSource.VIDEO_UPLOAD.key,
|
|
147
|
+
supportedMimeTypes = listOf(
|
|
148
|
+
"video/mp4",
|
|
149
|
+
),
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
// Register gallery asset sources
|
|
153
|
+
listOf(
|
|
154
|
+
AssetSourceType.GalleryAllVisuals,
|
|
155
|
+
AssetSourceType.GalleryImage,
|
|
156
|
+
AssetSourceType.GalleryVideo,
|
|
157
|
+
).forEach { type ->
|
|
158
|
+
editorContext.engine.asset.addSource(
|
|
159
|
+
source = SystemGalleryAssetSource(
|
|
160
|
+
context = editorContext.engine.applicationContext,
|
|
161
|
+
type = type,
|
|
162
|
+
),
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
SystemGalleryPermission.setMode(systemGalleryConfiguration)
|
|
166
|
+
|
|
167
|
+
// Register text asset source
|
|
168
|
+
TypefaceProvider().provideTypeface(
|
|
169
|
+
engine = editorContext.engine,
|
|
170
|
+
name = "Roboto",
|
|
171
|
+
)?.let {
|
|
172
|
+
val textAssetSource = TextAssetSource(engine = editorContext.engine, typeface = it)
|
|
173
|
+
editorContext.engine.asset.addSource(textAssetSource)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// highlight-starter-kit-on-load-asset-sources
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The callback that is invoked right after [onCreateScene], after the scene is created.
|
|
180
|
+
*/
|
|
181
|
+
fun VideoConfigurationBuilder.onPostCreateScene() {
|
|
182
|
+
// Do nothing
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* The callback that is invoked as the last step of [onCreate].
|
|
187
|
+
* It always runs, no matter success or failure on previous steps.
|
|
188
|
+
*/
|
|
189
|
+
fun VideoConfigurationBuilder.onCreateFinally() {
|
|
190
|
+
showLoading = false
|
|
191
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
package ly.img.editor.configuration.video.callback
|
|
2
|
+
|
|
3
|
+
import kotlinx.coroutines.CancellationException
|
|
4
|
+
import ly.img.editor.configuration.video.VideoConfigurationBuilder
|
|
5
|
+
import ly.img.editor.configuration.video.model.ExportStatus
|
|
6
|
+
import ly.img.engine.MimeType
|
|
7
|
+
import java.nio.ByteBuffer
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The callback that is invoked when the export button is clicked.
|
|
11
|
+
*/
|
|
12
|
+
suspend fun VideoConfigurationBuilder.onExport(
|
|
13
|
+
preExport: suspend VideoConfigurationBuilder.() -> Unit = {
|
|
14
|
+
onPreExport()
|
|
15
|
+
},
|
|
16
|
+
exportByteBuffer: suspend VideoConfigurationBuilder.() -> ByteBuffer = {
|
|
17
|
+
onExportByteBuffer()
|
|
18
|
+
},
|
|
19
|
+
postExport: suspend VideoConfigurationBuilder.(ByteBuffer) -> Unit = {
|
|
20
|
+
onPostExport(it)
|
|
21
|
+
},
|
|
22
|
+
error: suspend VideoConfigurationBuilder.(Exception) -> Unit = {
|
|
23
|
+
onExportError(it)
|
|
24
|
+
},
|
|
25
|
+
finally: suspend VideoConfigurationBuilder.() -> Unit = {
|
|
26
|
+
onExportFinally()
|
|
27
|
+
},
|
|
28
|
+
) {
|
|
29
|
+
try {
|
|
30
|
+
preExport()
|
|
31
|
+
val result = exportByteBuffer()
|
|
32
|
+
postExport(result)
|
|
33
|
+
} catch (exception: Exception) {
|
|
34
|
+
error(exception)
|
|
35
|
+
} finally {
|
|
36
|
+
finally()
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The callback that is invoked before the export is started.
|
|
42
|
+
*/
|
|
43
|
+
fun VideoConfigurationBuilder.onPreExport() {
|
|
44
|
+
exportStatus = ExportStatus.Loading(progress = 0F)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The callback that exports the content of the editor into [ByteBuffer].
|
|
49
|
+
*/
|
|
50
|
+
// highlight-starter-kit-on-export-byte-buffer
|
|
51
|
+
suspend fun VideoConfigurationBuilder.onExportByteBuffer(): ByteBuffer {
|
|
52
|
+
val targetDesignBlock = requireNotNull(editorContext.engine.scene.getCurrentPage())
|
|
53
|
+
return editorContext.engine.block.exportVideo(
|
|
54
|
+
block = targetDesignBlock,
|
|
55
|
+
timeOffset = 0.0,
|
|
56
|
+
duration = editorContext.engine.block.getDuration(targetDesignBlock),
|
|
57
|
+
mimeType = MimeType.MP4,
|
|
58
|
+
progressCallback = { progress ->
|
|
59
|
+
val lastExportStatus = exportStatus
|
|
60
|
+
val newProgress = progress.encodedFrames.toFloat() / progress.totalFrames
|
|
61
|
+
// Update export UI whenever the progress changes
|
|
62
|
+
if (lastExportStatus !is ExportStatus.Loading || newProgress >= lastExportStatus.progress + 0.01F) {
|
|
63
|
+
exportStatus = ExportStatus.Loading(progress = newProgress)
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
// highlight-starter-kit-on-export-byte-buffer
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The callback that is invoked after [onExportByteBuffer] and handles its output.
|
|
72
|
+
*/
|
|
73
|
+
// highlight-starter-kit-on-post-export
|
|
74
|
+
suspend fun VideoConfigurationBuilder.onPostExport(byteBuffer: ByteBuffer) {
|
|
75
|
+
val file = writeToFile(byteBuffer = byteBuffer, mimeType = MimeType.MP4)
|
|
76
|
+
exportStatus = ExportStatus.Success(file = file, mimeType = MimeType.MP4)
|
|
77
|
+
}
|
|
78
|
+
// highlight-starter-kit-on-post-export
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The callback that is invoked in case any of the export functions throw an exception.
|
|
82
|
+
*/
|
|
83
|
+
fun VideoConfigurationBuilder.onExportError(error: Exception) {
|
|
84
|
+
if (error is CancellationException) {
|
|
85
|
+
exportStatus = null
|
|
86
|
+
throw error
|
|
87
|
+
} else {
|
|
88
|
+
exportStatus = ExportStatus.Error(exception = error)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* The callback that is invoked as the last step of [onExportByteBuffer].
|
|
94
|
+
* It always runs, no matter success or failure on previous steps.
|
|
95
|
+
*/
|
|
96
|
+
fun VideoConfigurationBuilder.onExportFinally() {
|
|
97
|
+
showCancelExportConfirmationDialog = false
|
|
98
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package ly.img.editor.configuration.video.callback
|
|
2
|
+
|
|
3
|
+
import androidx.compose.ui.unit.dp
|
|
4
|
+
import ly.img.editor.configuration.video.VideoConfigurationBuilder
|
|
5
|
+
import ly.img.editor.core.component.data.Insets
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The callback that is invoked when the editor is loaded and ready to be used.
|
|
9
|
+
*/
|
|
10
|
+
suspend fun VideoConfigurationBuilder.onLoaded() {
|
|
11
|
+
observeEditorEditMode(
|
|
12
|
+
extraInsets = {
|
|
13
|
+
if (it == "Crop") {
|
|
14
|
+
Insets(value = 24.dp)
|
|
15
|
+
} else {
|
|
16
|
+
Insets(horizontal = 16.dp, vertical = 8.dp)
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
)
|
|
20
|
+
}
|