**Design Doc of Placeholder** *Last updated: August 8th 2018* Overview ===== `Placeholder` is designed for drag-and-drop interaction in Layout Editor. It is a replacement of all `DragTarget`s. `Placeholder` describes the area for dropping mouse, how component snaps it, and the callback function when dropping the component on it. The callback function is used for setting the attributes after dropping the Widget. We also has `CommonDragTarget` which takes responsibilities to update component position and interact with `Placeholder`s. How It Works ===== When user starts dragging a component, we create a `CommonDragTarget` which traces the mouse position and collect `Placeholder`s from `Scene`. `CommonDragTarget` snaps to the collected `Placeholder`s and update the proper positions of dragged component. Once mouse is released, `CommonDragTarget` finds the effect `Placeholder` and apply the callback of it to update the attributes. Implement a `Placeholder` ===== For creating a new Placeholder, simply extends the `Placeholder` interface and custom the part you need. There are 4 functions for overriding: - `val region: Region` - `fun snap(left: Int, top: Int, right: Int, bottom: Int): Boolean` - `fun updateAttributes(SceneComponent): Boolean` - (optional) `val nextComponent: SceneComponent?` `val region: Region` ----- For describing the receivable area. `CommonDragTarget` renders this region as well. It also has `level` attribute, which is used to determine the priority when regions are overlapped. For now all region is a rectangle. `fun snap(left: Int, top: Int, right: Int, bottom: Int): Boolean` ----- The arguments describe the expected area of dragged widget. `snap` function checks if the dragged widget should effect to this `Placeholder` `fun updateAttributes(SceneComponent): Boolean` ----- Callback for updating specified attributes when this `Placeholder` is applied. (optional) `val nextComponent: SceneComponent?` ----- If the applied widget has to be inserted to specified position in Xml file, override this value to the next `SceneComponent` of it. By default this value is `null`, which means the applied widget will be inserted to the end of it parent. After having a custom `Placeholder`, override `getPlaceholders(SceneComponent)` function in associated `ViewHandler` to provide them.
The `CommonDragTarget` will collect and interact with them automatically. References ===== [DesignDoc](https://docs.google.com/document/d/1HbxrqHMkdzjFAYhVJikp6bQVpBbaUsjmALtLpg-g_iw/edit?usp=sharing)