Search Docs
Loading...
Skip to content

Panel

A panel is a UI layer that displays above the canvas, and allows the user perform a scoped task like accessing asset library, selecting filters, or any custom action.

Panel on Android

Controlling a Panel#

Panels are implemented as different types of SheetType that allow you to display content in standard sheet overlays. Panels are opened using the EditorEvent.Sheet.Open event, and passing in the desired sheetType

editorContext.eventHandler.send(
EditorEvent.Sheet.Open(
SheetType.LibraryAdd(),
),
)

After use, they can be closed using the EditorEvent.Sheet.Close event.

editorContext.eventHandler.send(
EditorEvent.Sheet.Close(animate = true),
)

The boolean parameter indicates whether the panel should be closed with animation.

Creating a Custom Panel#

To create a custom panel, you can make a new SheetType.Custom() and define your UI inside the content parameter.

SheetType.Custom(
style = SheetStyle(
isFloating = false,
minHeight = Height.Exactly(0.dp),
maxHeight = Height.Fraction(0.7F),
isHalfExpandingEnabled = false,
isHalfExpandedInitially = true,
animateInitialValue = true,
),
content = {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text("Custom Panel")
Button(
onClick = {
editorContext.eventHandler.send(
EditorEvent.Sheet.Close(animate = true),
)
},
) { Text("Close Panel") }
}
},
)

In the style parameter, you can define how the sheet will look like. These are the parameters available for SheetStyle constructor, and what they change:

ParameterDefault ValueDescription
isFloatingfalsewhether the sheet should be floating. If true the sheet will be rendered over the editor, if false then the canvas will be zoomed to adjust the sheet.
minHeightHeight.Exactly(0.dp)the minimum height of the sheet.
maxHeightHeight.Fraction(0.5f)the maximum height of the sheet. If null, then there is no limit to the height. Once the maximum height is reached, the content of the sheet becomes vertically scrollable, if it is supported. Note that if you need the content to be scrollable in SheetType.Custom, then you need to add it manually.
isHalfExpandingEnabledfalsewhether the sheet should have a half expanded state. If false, then the sheet gets only 2 states: hidden and expanded.
isHaldExpandedInitiallyfalsewhether the sheet should be opened as half expanded initially. This flag takes effect only if isHalfExpandingEnabled is true.
animateInitialValuetruewhether initial expanded or half-expanded state should be animated.

Default Sheet Types#

The editor provides several built-in sheet types for common functionality:

Panel TypeDescription
SheetType.LibraryAdd()Display LibraryCategory in order to add assets to the scene
SheetType.LibraryReplace()Display LibraryCategory in order to replace assets in the scene
SheetType.Reorder()Reorder videos on the background track
SheetType.Adjustments()Make adjustments to design blocks with image and video fills
SheetType.Filter()Set filters to design blocks with image and video fills
SheetType.Effect()Set effects to design blocks with image and video fills
SheetType.Blur()Set blurs to design blocks with image and video fills
SheetType.Crop()Crop design blocks with image and video fills
SheetType.Layer()Control the layering of design blocks
SheetType.FormatText()Control formatting of text blocks
SheetType.Shape()Control the shape of various blocks
SheetType.FillStroke()Control the fill and/or stroke of various blocks
SheetType.Volume()Control the volume of audio/video
SheetType.Animation()Set in/out/loop animation to design blocks

Full source code#

Default Panel Solution#

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.KeyboardArrowUp
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.navigation.NavHostController
import ly.img.editor.Editor
import ly.img.editor.core.component.Dock
import ly.img.editor.core.component.EditorComponentId
import ly.img.editor.core.component.remember
import ly.img.editor.core.configuration.EditorConfiguration
import ly.img.editor.core.configuration.remember
import ly.img.editor.core.event.EditorEvent
import ly.img.editor.core.sheet.SheetType
@Composable
fun DefaultPanelSolution(navController: NavHostController) {
Editor(
license = null, // pass null or empty for evaluation mode with watermark
configuration = {
EditorConfiguration.remember {
dock = {
Dock.remember {
listBuilder = {
Dock.ListBuilder.remember {
add { openPanelDockButton }
}
}
}
}
}
},
) {
navController.popBackStack()
}
}
val openPanelDockButton
@Composable get() = Dock.Button.remember {
id = { EditorComponentId("open_library_panel") }
text = { Text("Open Library") }
icon = { Icon(Icons.Rounded.KeyboardArrowUp, null) }
onClick = {
editorContext.eventHandler.send(
EditorEvent.Sheet.Open(
SheetType.LibraryAdd(),
),
)
}
}

Custom Panel Solution#

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.KeyboardArrowUp
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import ly.img.editor.Editor
import ly.img.editor.core.component.Dock
import ly.img.editor.core.component.EditorComponentId
import ly.img.editor.core.component.data.Height
import ly.img.editor.core.component.remember
import ly.img.editor.core.configuration.EditorConfiguration
import ly.img.editor.core.configuration.remember
import ly.img.editor.core.event.EditorEvent
import ly.img.editor.core.sheet.SheetStyle
import ly.img.editor.core.sheet.SheetType
@Composable
fun CustomPanelSolution(navController: NavHostController) {
Editor(
license = null, // pass null or empty for evaluation mode with watermark
configuration = {
EditorConfiguration.remember {
dock = {
Dock.remember {
horizontalArrangement = { Arrangement.Center }
listBuilder = {
Dock.ListBuilder.remember {
add { openCustomPanelDockButton }
}
}
}
}
}
},
) {
navController.popBackStack()
}
}
val openCustomPanelDockButton
@Composable get() = Dock.Button.remember {
id = { EditorComponentId("open_panel") }
text = { Text("Open Panel") }
icon = { Icon(Icons.Rounded.KeyboardArrowUp, null) }
onClick = {
editorContext.eventHandler.send(
EditorEvent.Sheet.Open(customSheetType),
)
}
}
val customSheetType: SheetType
get() =
SheetType.Custom(
style = SheetStyle(
isFloating = false,
minHeight = Height.Exactly(0.dp),
maxHeight = Height.Fraction(0.7F),
isHalfExpandingEnabled = false,
isHalfExpandedInitially = true,
animateInitialValue = true,
),
content = {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text("Custom Panel")
Button(
onClick = {
editorContext.eventHandler.send(
EditorEvent.Sheet.Close(animate = true),
)
},
) { Text("Close Panel") }
}
},
)