Package com.smartgwt.client.docs

# Interface DevTools

public interface DevTools

### Dashboards & Tools Framework Overview

The Dashboards & Tools framework enables you to build interfaces in which a set of UI components can be edited by end users, saved and later restored.

This includes interfaces such as:

- Dashboards: where a library of possible widgets can be created & configured, arranged into freehand or portal-style layouts, then stored for future use and shared with other users
- Diagramming & Flowchart tools: tools similar to Visio™ which allow users to use shapes and connectors to create a flowchart or diagram representing a workflow, equipment or locations being monitored, a storyboard, or any similar interactive & modifiable visualization.
- Form Builders & Development Tools: tools which enable end users to create new forms or new screens, define interactive behaviors and rules, and add the screens to an application on the fly

### Overview

Dashboards & Tools provides a pattern for end user creation and configuration of UI components which enables the framework to store and re-create components exactly as the user configured them.

Unlike simple serialization, Dashboards & Tools is designed to capture only UI state created directly by end user actions, and not transient or derived state (for more on this behavior and how it is different from serialization, see "Stored vs Derived State" below).

To achieve this, user-editable components are created via a special pattern (not just the usual `new SomeComponent()`), and changes to user-editable components that are meant to be saved are likewise applied via special APIs (not just direct calls to `someComponent.setSomething()`).

The main components and behaviors involved in Dashboards & Tools are covered in brief below - each of these points is covered in more detail in further sections:

- User-editable components are created by `Palettes`. `Palettes` create components from `PaletteNodes`, which are `data records` containing the component's class and default settings. Some `Palettes` provide an end user UI for creating components (eg drag a node from a Tree).
- An editable component created by a `Palette` is represented by an `EditNode`, which tracks the created component along with the data necessary to save and re-create the component.
- An `EditContext` manages a list or `Tree` of `EditNodes`, and provides APIs for serializing and restoring `EditNodes` to and from XML and JSON, and updating the nodes as users make changes.
- Many UI components have `"edit mode"` behaviors. When "edit mode" is enabled, when an end user interacts with the component, the component will save changes to its `EditNode` or to child `EditNodes` in the `EditContext`. For example, `PortalLayout` can track and persist changes to the placement and size of portlets made by end users. `EditMode` behaviors are implemented by `EditProxies`, and different edit mode behaviors can be turned on and off for different kinds of tools.

A simple tool based on the Dashboards & Tools framework would typically consist of:

- one or more `Palettes` showing components that the user can create
- a main editing area where you can drag things from a `Palette` to create them. The editing area is just an ordinary UI component that has been placed into "edit mode" and provided with an `EditContext`. Depending on the type of tool, the main editing area might be a `DrawPane` (for diagrams), a `DynamicForm` (for a form builder) or various other widgets.
- Buttons, Menus and pop-up dialogs that act on the currently selected widget. Dashboards & Tools has `built-in UI` for selecting one or more of the components being edited. `EditContext.getSelectedEditNode()` provides the current edit node, and `EditContext.setNodeProperties()` lets you manipulate its persisted state.
- Buttons, Menus and pop-up dialogs providing the ability to load or save. These would use APIs on `EditContext` to `obtain XML or JSON Strings` representing the data to be saved, as well as to `restore saved state` from such Strings. DataSources can be used to store whatever is being edited: the serialized form is just an XML or JSON String, so it can be stored as an ordinary `DataSourceField` value.

### Creating editable components: `Palettes`

User-editable components are created by `Palettes`. `Palettes` create components from `PaletteNodes`, which are `data records` containing the component's class and default settings.

Most types of `palettes` provide a UI for an end user to create components from `paletteNodes`. For example, a `TreePalette` presents a hierarchical set of `paletteNodes` as a tree, and allows end users to drag nodes out in order to create components. All `palettes` also support `programmatic creation of components` from `paletteNodes`.

`paletteNodes` can be programmatically provided to a `Palette`, or, `Palettes` that are derived from `DataBoundComponents` can load `paletteNodes` from a `DataSource`.

When a component is created from a `paletteNode`, an `EditNode` is created that tracks the `live component` and the state needed to re-create it, called the `defaults`.

### EditContexts & EditProxies

An `EditContext` manages a `Tree` of `EditNodes`, and provides APIs for serializing and restoring `EditNodes` and updating the tree of nodes.

When an `EditNode` is added to an EditContext, typically it is immediately placed into `"Edit Mode"` (see `EditContext.autoEditNewNodes` for how this can be controlled). In Edit Mode, components introduce special behaviors, such as the ability to directly edit the titles of `Tab`s in a `TabSet` by double-clicking, or support for dragging new `FormItem`s into a `DynamicForm`. Changes made while a component is in Edit Mode are saved to the component's `EditNode`, in `EditNode.defaults`.

Each component that has `editMode` features has a corresponding `EditProxy` that implements those features. A component's `EditProxy` is automatically created when a component `goes into edit mode`, and overrides the normal behavior of the component. By configuring the `EditProxy` for a component, you configure what behaviors the component will have when in edit mode, and which specific actions on the component will cause changes to be saved to its `EditNode`.

For example, `CanvasEditProxy` has features for `saving coordinates as child widgets are dragged`, and `GridEditProxy` has features for persisting `field visibility` when end users show and hide fields.

You can configure which EditProxy behaviors are active via `PaletteNode.editProxyProperties` and `EditNode.editProxyProperties`, and via the `editProxy AutoChild`.

### EditContext & Trees of EditNodes

The `EditContext` has the capability to manage a `Tree` of `EditNodes` in order to enable tools that create a hierarchy of Smart GWT components. When you use `EditContext.addNode()` and add a new EditNode underneath another EditNode, the EditContext will automatically try to determine how the parent and child are related and actually call APIs on the widgets to establish a relationship, such as a Tab being added to a TabSet, or a FormItem being added to a DynamicForm. The EditContext uses the same approach as is used for Reify Drag and Drop - see `Reify overview` for details.

Note that many if not most kinds of tools use only a flat list of EditNodes - for example, in a collage editor, photos may sometimes be stacked on top of each other, but a parent/child relationship in the sense of `Canvas.children` is not established by doing so. Likewise, although the Mockup Editor sample allows end users to create mockups using Smart GWT components, the components never truly become children of other components. Instead, as is typical of most mockup tools, hierarchy is achieved visually by simply placing a component on top of another and within its bounding rectangle.

Most types of tools use a flat list of `EditNodes` - generally speaking you will only use the hierarchy management features of `Editcontext` if you are creating a tool that actually allows end users to build functioning Smart GWT screens, such as the Form Builder example. For such applications, use `EditContext.allowNestedDrops` to enable drag and drop interactions that will allow end users to place components inside of other components.

### Stored vs Derived state

The purpose of having an `EditNode` for each UI component is to maintain a distinction between the current state of the live UI component and the state that should be saved. For example:

- a component may have a current width of 510 pixels when viewed within a tool, but what should persist is the configured width of 40% of available space
- a component may have editing behaviors enabled, such as the ability to double-click to edit labels or titles, which should be enabled in the tool but not at runtime
- a tool may allow end users to create a Window, and then drag components into the Window. Every Window automatically creates subcomponents such as a header, but these should not be persisted because they don't represent state created by the end user. Only the components the end user actually dragged into the Window should be persisted
- an end user may try out the effect of a property change, then abandon it and revert to the default value. We don't want the temporary change saved, and we don't even want to save the reversion to the default value - nothing about the saved state should be changed

By being careful to save only intentional changes made by the user:

- the saved state remains minimal in size, and re-creating components from the stored state is more efficient
- the saved state is much easier to edit since it contains only intentional settings, and not generated or derived information
- the stored state is more robust against changes over time and easier to re-use. When we avoiding spuriously saving default values that the user has not modified, we avoid possible conflicts when a saved UI is deployed to a new version or in a different environment with different defaults

Specifically, only two things affect the state that will be stored for a given component:

1. Features enabled when a component is in EditMode, configured via the component's EditProxy
2. Direct calls to `EditContext.setNodeProperties()` by application code

Any other kind of change to the widget is not automatically persisted.

### Deriving default settings for PaletteNodes

PaletteNodes contain a set of default settings which define the initial properties for any live object created from that PaletteNode. When you create a PaletteNode directly, you configure these defaults by creating a properties object of the same type as the object represented by the PaletteNode, and passing it to the PalleteNode's `setCanvasDefaults()` method (PaletteNode also has equivalent `setFormItemDefaults()` and `setDrawItemDefaults()` methods).

Sometimes, however, your code does not directly create the PaletteNode itself. For example, when you provide `TileRecord`s that will be used in a `TilePalette`, you provide the PaletteNode defaults on the TileRecords, but your code does not actually create the PaletteNodes. In this case, you create a properties object as described above, and then you call its `getPaletteDefaults()` method to obtain a Map of properties suitable for specifying PaletteNode defaults. This code, taken from the Collage Editor sample, demonstrates the approach:

          Img img = new Img();
          img.setTitle(title);
          img.setSrc("stockPhotos/" + photos.get(i));
          TileRecord record = new TileRecord();
          record.setAttribute("title", title);
          record.setAttribute("type", "Img");
          record.setAttribute("defaults", img.getPaletteDefaults());

### Module requirements

NOTE: you must load the Tools `Optional Module` for this framework.

Any tools that work with hierarchies of system components or derivations of them will also need the system schema which can be loaded by either of the following:

JSP tag:

    <script><isomorphic:loadSystemSchema /></script>

HTML tag:

    <SCRIPT SRC="../isomorphic/DataSourceLoader?dataSource=$systemSchema"></SCRIPT>

See Also:
  - `EditContext`
  - `SerializationSettings`
  - `Palette`
  - `HiddenPalette`
  - `TreePalette`
  - `ListPalette`
  - `TilePalette`
  - `MenuPalette`
  - `EditPane`
  - `EditTree`
  - `EditProxy`
  - `CanvasEditProxy`
  - `LayoutEditProxy`
  - `SplitPaneEditProxy`
  - `TabSetEditProxy`
  - `StatefulCanvasEditProxy`
  - `ImgEditProxy`
  - `LabelEditProxy`
  - `ProgressbarEditProxy`
  - `WindowEditProxy`
  - `DetailViewerEditProxy`
  - `MenuEditProxy`
  - `SectionStackEditProxy`
  - `SectionStackSectionEditProxy`
  - `FormEditProxy`
  - `FormItemEditProxy`
  - `FileItemEditProxy`
  - `TextItemEditProxy`
  - `TextAreaItemEditProxy`
  - `ToolbarItemEditProxy`
  - `SelectItemEditProxy`
  - `SavedSearchItemEditProxy`
  - `CheckboxItemEditProxy`
  - `DateItemEditProxy`
  - `GridEditProxy`
  - `DrawPaneEditProxy`
  - `DrawItemEditProxy`
  - `DrawLabelEditProxy`
  - `FacetChartEditProxy`
  - `com.smartgwt.client.tools.EditContext#screenMode`
  - `com.smartgwt.client.tools.EditContext#editNodePasteOffset`
  - `EditContext.getRootComponent()`
  - `Palette.getGenerateNames()`
  - `TreePalette.getComponentDefaults()`
  - `EditPane.getRootComponent()`
  - `EditTree.getRootComponent()`