In this example, we will show you how to make inspector bar configurations for the mobile editor. The example is based on the Design Editor
, however, it is exactly the same for all the other solutions.
Explore a full code sample on GitHub.
Inspector Bar Architecture#
InspectorBar
is a list of items placed horizontally at the bottom of the editor. It is visible when a design block is selected and its items provide different editing capabilities to the selected design block.
It has type InspectorBar : EditorComponent
and every item in the inspector bar has type InspectorBar.Item : EditorComponent
. InspectorBar.Item
is an abstract class that currently has two implementations:
InspectorBar.Button
and InspectorBar.Custom
. InspectorBar.Button
is an editor component that has an icon and a text positioned in a column, while InspectorBar.Custom
is a fully custom editor component that allows drawing arbitrary content.
Prefer using InspectorBar.Custom
for rendering custom content in the inspector bar over inheriting from InspectorBar.Item
.
InspectorBar Configuration#
InspectorBar
is part of the EditorConfiguration
, therefore, in order to configure the inspector bar we need to configure the EditorConfiguration
.
Below you can find the list of available configurations of the inspector bar. To demonstrate the default values, all parameters are assigned to their default values.
scope
- the scope of this component. Every new value will trigger recomposition of all the lambda parameters below. If you need to accessEditorScope
to construct the scope, useLocalEditorScope
. Consider using ComposeState
objects in the lambda parameters below for granular recompositions over updating the scope, since scope change triggers full recomposition of the inspector bar. Prefer updating individualInspectorBar.Item
s over updating the whole inspector bar. Ideally, scope should be updated when the parent scope (scope of the parent component) is updated and when you want to observe changes from theEngine
. By default the scope is updated when the parent scope (accessed viaLocalEditorScope
) is updated, when selection is changed to a different design block (or unselected) and when the parent of the currently selected design block is changed to a different design block.
-
inspectorBarItems
- the@InspectorBar.Builder
that registers theInspectorBar.Item
s and defines their order. Note that registering does not mean displaying. The items will be displayed ifInspectorBar.Item.isVisible(_:)
returns true for them. By default, the items shown in this example are defined for all editor solutions. -
modifyInspectorBarItems
- the modifications that should be applied to the order of items defined by the.imgly.inspectorBarItems
builder above. This modifier can be used, when you do not want to touch the default general order of the items, but rather add additional items and replace/hide some of the default items. To achieve that, use theInspectorBar.Modifier
provided as the second closure argument, nameditems
in this example, to add, replace, and remove items as highlighted in modify inspector bar items. By default, no modifications are applied.
-
exitTransition
- transition of the inspector bar when it exits the parent composable. Default value is a top to bottom vertical transition. -
decoration
- decoration of the inspector bar. Useful when you want to add custom background, foreground, shadow, paddings etc. By default decoration adds background color, applies paddings and adds a close button to the inspector bar. -
listBuilder
- a builder that registers the list ofInspectorBar.Item
s that should be part of the inspector bar. Note that registering does not mean displaying. The items will be displayed ifInspectorBar.Item.visible
is true for them. By defaultInspectorBar.ListBuilder.remember
is used. For more details, see ListBuilder Configuration section. -
horizontalArrangement
- the horizontal arrangement that should be used to render the items in the inspector bar horizontally. Default value isArrangement.Start
. -
itemsRowEnterTransition
- separate transition of the items’ row only whenenterTransition
is running. Default value is a right to left horizontal transition. -
itemsRowExitTransition
- separate transition of the items’ row only whenexitTransition
is running. Default value is always no exit transition. -
itemDecoration
- decoration of the items in the inspector bar. Useful when you want to add custom background, foreground, shadow, paddings etc to the items. Prefer using this decoration when you want to apply the same decoration to all the items, otherwise set decoration to individual items. Default value is always no decoration.
InspectorBar.ListBuilder Configuration#
There are two main ways to create an instance of InspectorBar.ListBuilder
. First way is to call modify
on an existing builder, and the second way is to create the builder from scratch.
Currently, there is a single available builder, accessible via InspectorBar.ListBuilder.remember
. It provides a single general order of items in the inspector bar.
There is a visibility information next to each item that mentions for which design blocks/fill types the item is going to be visible.
Modifying an Existing Builder#
In this example, we will modify the only available builder: InspectorBar.ListBuilder.remember
. Modifying builders can be used, when you do not want to touch the default general order of the items in the builder, but rather add additional items and replace/hide some of the default items. To achieve that, there are multiple available functions in the scope of modify
lambda:
-
addFirst
- prepends a newInspectorBar.Item
in the list. -
addLast
- appends a newInspectorBar.Item
in the list. -
addAfter
- adds a newInspectorBar.Item
right after the item with provided id. An exception will be thrown if no item exists with provided id in the default builder. -
addBefore
- adds a newInspectorBar.Item
right before the item with provided id. An exception will be thrown if no item exists with provided id in the default builder. -
replace
- replaces theInspectorBar.Item
with provided id. An exception will be thrown if no item exists with provided id in the default builder. Also note that the new item does not need to have the same id. -
remove
- removes theInspectorBar.Item
with provided id. An exception will be thrown if no item exists with provided id in the default builder.
Creating a New Builder#
In this example, we will create a builder from scratch that will be used in the InspectorBar
of DesignEditor
solution.
Creating a new builder is recommended, when you do not want to use the default order of items provided by IMG.LY.
This example mimics reordering the default order of items in InspectorBar.ListBuilder.remember
builder. In addition, some items are removed and a new custom item is prepended.
InspectorBar.Item Configuration#
As mentioned in the Inspector Bar Architecture section, InspectorBar.Item
conforms to EditorComponent
. Its id
must be unique which is a requirement of the underlying SwiftUI ForEach
type.
Depending on your needs there are multiple ways to define an item. In this example, we demonstrate your options with increasing complexity.
InspectorBar.Button Configuration#
The most basic option is to use our predefined buttons which are provided in the nested InspectorBar.Buttons.
namespace. All available predefined buttons are listed below.
-
id
- the id of the button. Note that it is highly recommended that every uniqueEditorComponent
has a unique id. Parameter does not have a default value. -
scope
- the scope of this component. Every new value will trigger recomposition of all the lambda parameters below. If you need to accessEditorScope
to construct the scope, useLocalEditorScope
. Consider using ComposeState
objects in the lambda parameters below for granular recompositions over updating the scope, since scope change triggers full recomposition of the button. Ideally, scope should be updated when the parent scope (scope of the parent componentInspectorBar
-InspectorBar.Scope
) is updated and when you want to observe changes from theEngine
. By default the scope is updated only when the parent component scope (InspectorBar.scope
, accessed viaLocalEditorScope
) is updated. -
visible
- whether the button should be visible. Default value is always true. -
enterTransition
- transition of the button when it enters the parent composable. Default value is always no enter transition. -
exitTransition
- transition of the button when it exits the parent composable. Default value is always no exit transition. -
decoration
- decoration of the button. Useful when you want to add custom background, foreground, shadow, paddings etc. Default value is always no decoration. -
onClick
- the callback that is invoked when the button is clicked. Parameter does not have a default value. -
icon
- the icon content of the button. If null, it will not be rendered. Default value is null. -
text
- the text content of the button. If null, it will not be rendered. Default value is null. -
enabled
- whether the button is enabled. Default value is always true.
Other than the main InspectorBar.Button.remember
function, there is one more convenience overload that has three differences:
icon
is replaced withvectorIcon
lambda, that returnsVectorIcon
instead of drawing the icon content.text
is replaced withtext
lambda, that returnsString
instead of drawing the text content.- An extra parameter
contentDescription
is added that is used by accessibility services to describe what the button does. Note that it is not required to provide value whentext
is not null, since its value will be used by accessibility services, however having bothtext
andcontentDescription
as null will cause a crash.
InspectorBar.Custom Configuration#
In order to create a custom inspector bar item, use InspectorBar.Custom.remember
composable function. Below you can find the list of available configurations when creating a InspectorBar.Custom
item. To demonstrate the default values, all parameters are assigned to their default values whenever possible.
-
id
- the id of the custom item. Note that it is highly recommended that every uniqueEditorComponent
has a unique id. Parameter does not have a default value. -
scope
- the scope of this component. Every new value will trigger recomposition of all the lambda parameters below. If you need to accessEditorScope
to construct the scope, useLocalEditorScope
. Consider using ComposeState
objects in the lambda parameters below for granular recompositions over updating the scope, since scope change triggers full recomposition of the custom item. Ideally, scope should be updated when the parent scope (scope of the parent componentInspectorBar
-InspectorBar.Scope
) is updated and when you want to observe changes from theEngine
. Parameter does not have a default value. -
visible
- whether the custom item should be visible. Default value is always true. -
enterTransition
- transition of the custom item when it enters the parent composable. Default value is always no enter transition. -
exitTransition
- transition of the custom item when it exits the parent composable. Default value is always no exit transition. -
content
- the content of the custom item. You are responsible for drawing it, handling clicks etc. Parameter does not have a default value.
List of Available InspectorBar.Buttons#
This is a comprehensive list of all predefined buttons. Some of them were already used in the previous sections. They are static functions that look like this: InspectorBar.Buttons.{name}
. All these functions return a InspectorBar.Button
. They are public and can be used in your application. Note that all the parameters of these functions have default values, therefore, you do not need to provide any values, however, if you want to modify any of the parameters, it is exactly the same as described in the Customize Predefined Buttons section.
Button | ID | Description | Renders For |
---|---|---|---|
InspectorBar.Buttons.replace | InspectorBar.Buttons.ID.replace | Opens a library sheet via editor event .openSheet . By default DesignBlockType , FillType and kind of the selected design block are used to find the library in the Asset Library. Selected asset will replace the content of the currently selected design block. | Video, Image, Sticker, Audio |
InspectorBar.Buttons.editText | InspectorBar.Buttons.ID.editText | Enters text editing mode for the selected design block. | Text |
InspectorBar.Buttons.formatText | InspectorBar.Buttons.ID.formatText | Opens format text sheet via editor event .openSheet . | Text |
InspectorBar.Buttons.fillStroke | InspectorBar.Buttons.ID.fillStroke | Opens fill & stroke sheet via editor event .openSheet . | Page, Video, Image, Shape, Text |
InspectorBar.Buttons.editVoiceover | InspectorBar.Buttons.ID.editVoiceover | Opens voiceover sheet via editor event .openSheet . | Video, Audio, Voiceover |
InspectorBar.Buttons.volume | InspectorBar.Buttons.ID.volume | Opens volume sheet via editor event .openSheet . | Video, Audio, Voiceover |
InspectorBar.Buttons.crop | InspectorBar.Buttons.ID.crop | Opens crop sheet via editor event .openSheet . | Video, Image |
InspectorBar.Buttons.adjustments | InspectorBar.Buttons.ID.adjustments | Opens adjustments sheet via editor event .openSheet . | Video, Image |
InspectorBar.Buttons.filter | InspectorBar.Buttons.ID.filter | Opens filter sheet via editor event .openSheet . | Video, Image |
InspectorBar.Buttons.effect | InspectorBar.Buttons.ID.effect | Opens effect sheet via editor event .openSheet . | Video, Image |
InspectorBar.Buttons.blur | InspectorBar.Buttons.ID.blur | Opens blur sheet via editor event .openSheet . | Video, Image |
InspectorBar.Buttons.shape | InspectorBar.Buttons.ID.shape | Opens shape sheet via editor event .openSheet . | Video, Image, Shape |
InspectorBar.Buttons.selectGroup | InspectorBar.Buttons.ID.selectGroup | Selects the group design block that contains the currently selected design block via editor event .selectGroupForSelection . | Video, Image, Sticker, Shape, Text |
InspectorBar.Buttons.enterGroup | InspectorBar.Buttons.ID.enterGroup | Changes selection from the selected group design block to a design block within that group via editor event .enterGroupForSelection . | Group |
InspectorBar.Buttons.layer | InspectorBar.Buttons.ID.layer | Opens layer sheet via editor event .openSheet . | Video, Image, Sticker, Shape, Text |
InspectorBar.Buttons.split | InspectorBar.Buttons.ID.split | Splits currently selected design block via editor event .splitSelection in a video scene. | Video, Image, Sticker, Shape, Text, Audio |
InspectorBar.Buttons.moveAsClip | InspectorBar.Buttons.ID.moveAsClip | Moves currently selected design block into the background track as clip via editor event .moveSelectionAsClip | Video, Image, Sticker, Shape, Text |
InspectorBar.Buttons.moveAsOverlay | InspectorBar.Buttons.ID.moveAsOverlay | Moves currently selected design block from the background track to an overlay via editor event .moveSelectionAsOverlay | Video, Image, Sticker, Shape, Text |
InspectorBar.Buttons.reorder | InspectorBar.Buttons.ID.reorder | Opens reorder sheet via editor event .openSheet . | Video, Image, Sticker, Shape, Text |
InspectorBar.Buttons.duplicate | InspectorBar.Buttons.ID.duplicate | Duplicates currently selected design block via editor event .duplicateSelection . | Video, Image, Sticker, Shape, Text, Audio |
InspectorBar.Buttons.delete | InspectorBar.Buttons.ID.delete | Deletes currently selected design block via editor event .deleteSelection . | Video, Image, Sticker, Shape, Text, Audio, Voiceover |