## Custom Component Architecture

### Component System

The component system makes up the foundation of the UI Designer. It provides components to the UI Designer from component library plugins or user component projects in the current workspace. In the UI Designer, each component is defined by an XML file, an associated set of JavaScript files, images, and sometimes Eclipse extension points.

Each component defines its related properties, property types, events, rendering, source generation, RSS mapping, editor icon and description. A component also defines its behavior for a specific part of the target program. Each component is typically a single control (e.g. CEikEdwin) or container (e.g. CAknView or CCoeControl), but are sometimes defined for portions of such controls when it is more convenient for implementation, for example individual items of CAknListBox. Components may also refer to instances of C++ classes (like active objects) or transient dialogs (like progress dialogs).

Components may derive from other components, allowing them to share, override, and augment key parts of another's implementation. However, only single inheritance is supported.

A component is defined by a unique ID (qualifiedName), which identifies it to other parts of the UI Designer. These are usually dotted names, for example, "com.nokia.sdt.series60.CAknForm". Components in the UI Designer are marked by an SDK vendor and version. Multiple components with the same unique ID may be defined, if each has a different SDK range. One or none will be selected for use in a design based on the baseline SDK selected, allowing the UI Designer to generate source and resources that are compatible with all SDKs in a project. Sometimes, generated source may compensate for SDK differences with #ifdefs, but this is exceedingly rare in practice.

Component definitions also include their own version, which means changes in component structure may be detected and acted upon by an update mechanism in Carbide.c++. It's important to design components strictly in accordance with the API versions they target. You want to be sure users will have compilable source no matter what SDK or combination of SDK's they select, even if they change build configurations for their project. Note that this means a component will not necessarily be available for all SDKs in use. The UI Designer can deal gracefully with components that are no longer available for a given SDK, but ample warnings are provided to prevent a design from being saved with a missing component.

### Data Model

The data model represents a design, wherein instances of components (component instances) are stored, along with their associated property settings and event bindings. The model as a whole also contains a shared language string table and source generation metadata. This design is generated into .uidesign files. The .uidesign files can be graphically displayed in the UI Designer editor or textually displayed in a text editor to reveal their generated XML structure.

The data model remembers the baseline SDK and component versions used for the last save, so it can detect when components are updated or when the related project's build configurations become incompatible with a design. This will prompt the user to take action.

The baseline SDK associated with a data model is used in conjunction with the component system to form a component set. The set is a collection of components which are valid for that configuration. The newest compatible component is selected for use in a design.

A UI design only references components by ID. This allows the structure of components to change without the UI design becoming invalid. Aside from the ID, only the names of properties and events are reflected in the design. Even types of properties are ignored and property values are stored as strings. Thus, a component may add or drop properties between versions, or add or drop events, or (within reason) change the types of properties, without rendering the UI design invalid. The data model will retain any properties that were set, even if they disappear from a component, usually allowing for a design to be converted to a newer or older component version without losing information.

Components may publish a dynamic set of properties based on runtime checks, allowing them to adapt to the requirements of other component instances. The S60 List Box, for example, uses the "style" property to control which properties are available on its child List Item component instances. Since the data model is flexible and retains properties that no longer exist, fields which relate to other styles may be swapped out without losing information. Thus, you can switch a list box from a "double large" style to a "double time" style to a "single text" style and back without losing any list item information.

When designing a component, it is important to consider how its data will be used and stored in the data model. Design for flexibility, constructing properties that are independent of each other (as much as possible) and which correspond to specific RSS member fields or C++ setter methods; so they may evolve in coordination with the APIs they are targeting. Also split components into pieces when they have a variable number of contained similar items, rather than making complex array properties.

### Display Model

A data model specifies a display model, which consists of various aspects on how the design is displayed on screen. It controls how the model is converted into a layout for use by the editor and how that layout is rendered into images. For S60, each component provides a bitmap with transparency and these are drawn on top of each other to make the composite screen.

A component also provides the applicable layout configurations (screen sizes and portrait/landscape orientations), which supply "look and feel" interfaces that abstract layout-dependent colors, points, rectangles, images, flags, and strings into named keys for use by components. This allows components to be written for any current or future layout. New components will need to implement the rendering interface "IVisualAppearance" to draw their contents onto a transparent bitmap, using SWT GC operations. Alternately, initial implementations can provide a static bitmap image to represent the component.

### Editor

The editor provides the user interaction with the data model and display model. It coordinates the editor document, palette, properties view, outline view, and events view. The editor's document represents the layout object tree, while the outline view represents the data model. The properties and events views show information for the currently selected item.

In the editor, the palette shows a filtered view of components available for the UI design. The containers in the model are queried for compatibility with each component (by the IQueryContainment interface) and only valid combinations are shown in the palette. This is not the full set of installed components. Thus, an important first step for developing new components is to understand how containment works and toggle the "Palette filtering" button in the toolbar so your components show up.

##### Related concepts

- Developing New Components