Skip to main content
Platform
Language

Configure Canvas Menu

In this example, we will show you how to make canvas menu 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.

Canvas Menu Architecture#


CanvasMenu is a list of items placed horizontally that is displayed when a design block is selected. Items in this list provide different editing capabilities to the selected design block. It has type CanvasMenu : EditorComponent and every item in the canvas menu has type CanvasMenu.Item : EditorComponent. CanvasMenu.Item is an abstract class that currently has three implementations: CanvasMenu.Button, CanvasMenu.Divider and CanvasMenu.Custom. CanvasMenu.Button is an editor component that has an icon and a text positioned in a column, CanvasMenu.Divider is a component that renders a divider between items, while CanvasMenu.Custom is a fully custom editor component that allows drawing arbitrary content. Prefer using CanvasMenu.Custom for rendering custom content in the canvas menu over inheriting from CanvasMenu.Item.

CanvasMenu Configuration#

CanvasMenu is part of the EditorConfiguration, therefore, in order to configure the canvas menu we need to configure the EditorConfiguration. Below you can find the list of available configurations of the canvas menu. 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 access EditorScope to construct the scope, use LocalEditorScope. Consider using Compose State objects in the lambda parameters below for granular recompositions over updating the scope, since scope change triggers full recomposition of the canvas menu. Prefer updating individual CanvasMenu.Items over updating the whole canvas menu. Ideally, scope should be updated when the parent scope (scope of the parent component) is updated and when you want to observe changes from the Engine. By default the scope is updated when the parent scope (accessed via LocalEditorScope) 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.
  • visible - whether the canvas menu should be visible. By default the value is true when a design block is selected, it is not part of a group, canvas is not moving (finger is not on canvas), selected design block does not have a type DesignBlockType.Audio or DesignBlockType.Page, no sheet is displayed currently and the keyboard is not visible. In addition, selected design block should be visible at current playback time and containing scene should be on pause if design block is selected in a video scene.
  • enterTransition - transition of the canvas menu when it enters the parent composable. Default value is always no enter transition.
  • exitTransition - transition of the canvas menu when it exits the parent composable. Default value is always no exit transition.
  • decoration - decoration of the canvas menu. Useful when you want to add custom background, foreground, shadow, paddings etc. By default decoration adds background color, applies rounded corners and positions the list of items next to the selected design block.
  • listBuilder - a builder that registers the list of CanvasMenu.Items that should be part of the canvas menu. Note that registering does not mean displaying. The items will be displayed if CanvasMenu.Item.visible is true for them. By default CanvasMenu.ListBuilder.remember is used. For more details, see ListBuilder Configuration section.
  • itemDecoration - decoration of the items in the canvas menu. 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.

CanvasMenu.ListBuilder Configuration#

There are two main ways to create an instance of CanvasMenu.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 CanvasMenu.ListBuilder.remember. It provides a single general order of items in the canvas menu.

Modifying an Existing Builder#

In this example, we will modify the only available builder: CanvasMenu.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 new CanvasMenu.Item in the list.
  • addLast - appends a new CanvasMenu.Item in the list.
  • addAfter - adds a new CanvasMenu.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 new CanvasMenu.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 the CanvasMenu.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 the CanvasMenu.Item with provided id. An exception will be thrown if no item exists with provided id in the default builder.

Warning#

Note that the order of items may change between editor versions, therefore ListBuilder.modify must be used with care. Consider creating a new builder if you want to have strict ordering between different editor versions.

Creating a New Builder#

In this example, we will create a builder from scratch that will be used in the CanvasMenu 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 CanvasMenu.ListBuilder.remember builder. In addition, some items are removed and a new custom item is prepended.

CanvasMenu.Item Configuration#

As mentioned in the CanvasMenu Architecture section, CanvasMenu.Item is an EditorComponent and it has two subtypes: CanvasMenu.Button and CanvasMenu.Custom.

CanvasMenu.Button Configuration#

In order to create a canvas menu button, use CanvasMenu.Button.remember composable function. Below you can find the list of available configurations when creating an CanvasMenu.Button. To demonstrate the default values, all parameters are assigned to their default values whenever possible.

  • id - the id of the button. Note that it is highly recommended that every unique EditorComponent 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 access EditorScope to construct the scope, use LocalEditorScope. Consider using Compose State 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 component CanvasMenu - CanvasMenu.Scope) is updated and when you want to observe changes from the Engine. By default the scope is updated only when the parent component scope (CanvasMenu.scope, accessed via LocalEditorScope) 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 CanvasMenu.Button.remember function, there is one more convenience overload that has two differences:

  1. icon is replaced with vectorIcon lambda, that returns VectorIcon instead of drawing the icon content.
  2. text is replaced with text lambda, that returns String instead of drawing the text content.

CanvasMenu.Divider Configuration#

In order to create a canvas menu divider, use CanvasMenu.Divider.remember composable function. Below you can find the list of available configurations when creating a CanvasMenu.Divider item. To demonstrate the default values, all parameters are assigned to their default values whenever possible.

  • scope - the scope of this component. Every new value will trigger recomposition of all the lambda parameters below. If you need to access EditorScope to construct the scope, use LocalEditorScope. Consider using Compose State 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 component CanvasMenu - CanvasMenu.Scope) is updated and when you want to observe changes from the Engine. Parameter does not have a default value.
  • visible - whether the divider should be visible. Default value is always true.
  • enterTransition - transition of the divider when it enters the parent composable. Default value is always no enter transition.
  • exitTransition - transition of the divider when it exits the parent composable. Default value is always no exit transition.
  • decoration - decoration of the divider. Useful when you want to add custom background, foreground, shadow, paddings etc. Default value is always no decoration.
  • modifier - the modifier of the divider. Default value is always a Modifier that sets size and paddings to the divider.

CanvasMenu.Custom Configuration#

In order to create a custom canvas menu item, use CanvasMenu.Custom.remember composable function. Below you can find the list of available configurations when creating a CanvasMenu.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 unique EditorComponent 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 access EditorScope to construct the scope, use LocalEditorScope. Consider using Compose State 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 component CanvasMenu - CanvasMenu.Scope) is updated and when you want to observe changes from the Engine. 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 CanvasMenu.Buttons#

As you often saw in the previous sections, there are composable functions that look like this: CanvasMenu.Button.remember{name}. All these functions return an CanvasMenu.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 CanvasMenu.Button Configuration section.

ButtonIdDescription
Button
CanvasMenu.Button.rememberBringForward
Id
CanvasMenu.Button.Id.bringForward
Description
Brings forward currently selected design block via EditorEvent.Selection.BringForward.
Button
CanvasMenu.Button.rememberSendBackward
Id
CanvasMenu.Button.Id.sendBackward
Description
Sends backward currently selected design block via EditorEvent.Selection.SendBackward.
Button
CanvasMenu.Button.rememberDuplicate
Id
CanvasMenu.Button.Id.duplicate
Description
Duplicates currently selected design block via EditorEvent.Selection.Duplicate.
Button
CanvasMenu.Button.rememberDelete
Id
CanvasMenu.Button.Id.delete
Description
Deletes currently selected design block via EditorEvent.Selection.Delete.