skip to main content
OpenEdge Development: AppBuilder
Multiple Layouts : Multiple layouts for SmartObjects
 
Multiple layouts for SmartObjects
Multiple layouts for SmartObjects are designed to provide alternate visualizations of a SmartObject, as might be required by use in different SmartContainers or by other functional criteria of the application, such as access privileges. Thus, the setup and initialization of a SmartObject layout is not primarily a function of the run‑time environment, but of the SmartContainer logic that instantiates the SmartObject.
For SmartObjects, multiple layouts are supported by these ADM properties:
*LayoutOptions — Contains a comma‑separated list of the layouts that you set up for a SmartObject in the AppBuilder at design time.
*LayoutVariable — Contains the layout that you choose (other than the default) for an instance of the SmartObject when you add it to a SmartContainer. (If you choose the default, the SmartObject uses the value of the DefaultLayout property.) This is also the variable that you set to change a SmartObject’s layout at run time.
*DefaultLayout — Contains the layout that the SmartObject uses if you do not set an ObjectLayout property value for an instance of the SmartObject. DefaultLayout is set based on the run‑time settings established in the Alternate Layout dialog box. If DefaultLayout has no value, the SmartObject uses the master layout.
*ObjectLayout — Contains the layout that the SmartObject uses.
Unlike the run‑time expressions used for basic procedure files, the setting of these properties does not immediately affect a SmartObject’s layout. Rather, the action of these properties depends on initialization of the SmartObject by its SmartContainer. At run time, the initializeObject() event procedure runs the layout cases internal procedure {&LAYOUT-VARIABLE} variables by running applyLayout. The applyLayout() event procedure uses the value of the ObjectLayout or DefaultLayout property to determine initial visualization for the SmartObject. At any point after initialization, you can choose a different layout for the SmartObject by setting and applying a different value to the ObjectLayout property (from LayoutOptions).
Creating SmartObject alternate layouts
You can create an alternate layout for a SmartObject or SmartContainer much like you do for a basic procedure file (see the “Creating alternate layouts” section). However, you should not enter a run‑time expression to determine the active layout. Figure 62 shows the Alternate Layout dialog box that appears for a SmartObject.
Figure 62: Alternate Layout dialog box for SmartObjects
This example shows the setting for an alternate Layout, Address Information, created for the SmartObject. Note the Don’t use Run‑time Expression option. This appears only for SmartObjects and is turned on by default. To activate a run‑time expression for this layout, turn off the option. The default setting when you turn it off is FALSE.
Modifying SmartObject layouts
You can modify and synchronize SmartObject layouts in the design window similar to basic procedure file layouts. (For more information, see the “Modifying layouts with layout inheritance” section.) However, SmartObject instances in a SmartContainer layout have additional features.
To illustrate working with SmartObject layouts, the rest of this section references a SmartDialog that contains a SmartDataViewer that has three layouts: a master and two alternates. The master layout, shown in Figure 63, contains many of the fields of the sports database Customer table, some of which overlay each other.
Figure 63: SmartDataViewer master layout
Each of the alternate layouts, shown in Figure 64 and Figure 65, displays or hides different sets of the fields in the master layout.
Figure 64: SmartDataViewer Address alternate layout
Figure 65: SmartDataViewer Balance alternate layout
In general, SmartObjects instances inherit the active layout of the parent SmartContainer in the AppBuilder. While the SmartContainer is in an alternate layout, you cannot set the ObjectLayout (or any other instance property) of the SmartObjects that it contains. To set the active layout of a SmartObject instance, the parent SmartContainer must be in the master layout. Also, once set, the layout for a SmartObject instance overrides any subsequent layout setting inherited from the parent SmartContainer. If you want the SmartContainer to change the layout of its SmartObjects dynamically, you can create an override createObjects() event procedure that sets the ObjectLayout properties of the SmartObjects after they are created.
Setting layout options for SmartObject instances
Several SmartObjects provided with OpenEdge include instance properties dialog boxes that allow you to set run‑time options for a SmartObject instance. For more information, see the “SmartObject properties” section. You can set instance properties only for a SmartObject displayed in the master layout of the parent SmartContainer, in the example, a SmartDialog.
You can access the Properties dialog box for an instance in two ways. One is to click on the instance menu button to display the pop‑up menu shown in Figure 66.
Figure 66: SmartDataViewer menu button’s pop‑up menu
This allows you to go directly to the Instance Properties dialog box by clicking on Instance Properties. Alternatively, you can click on Properties (or double‑click on the instance itself) to open the instance property sheet, then click on the Edit button to open the Instance Properties dialog box.
For the same SmartObject instance with the parent SmartContainer displayed in an alternate layout, the menu button’s pop‑up menu changes to prevent you from modifying any instance properties, as shown in Figure 67.
Figure 67: Menu button’s pop‑up menu in alternate layout
In this case, the Instance Properties option is insensitive and the Delete Instance option is replaced with the Remove from Layout option. Both Remove from Layout and Delete Instance hide the SmartObject from view. However, Remove from Layout only hides the SmartObject, while Delete Instance actually deletes it from the SmartContainer. Remove from Layout is used for alternate layouts rather than Delete Instance because the SmartObject instance is still available from the master layout of the SmartContainer.
Also, the instance property sheet changes in a SmartContainer alternate layout, as shown in Figure 68.
Figure 68: Instance property sheet in alternate layout
This is the property sheet for the SmartDataViewer instance in an alternate layout. Note that the Edit button is insensitive, preventing editing of the instance properties. The Remove from Layout option, the Layout inherited from the SmartContainer, and the Sync with Master button are also added to the property sheet. The Parameterize as Variable option, normally available in the master layout, is also insensitive.
This example illustrates how you might have an alternate layout standard for the windows and dialog boxes of an entire application, while maintaining the ability to apply instance‑specific layouts (Layout = Balance Information) for SmartObjects contained within these windows and dialog boxes. Thus, you might have two or more application visualizations in which the SmartObject instances retain the same functional layouts.
Two supported SmartObjects, SmartDataViewers and SmartDataBrowsers, support ObjectLayout as an instance property. You can set this property in the Instance Properties dialog box using the Layout combo box, as shown in Figure 69.
.
Figure 69: SmartDataViewer properties with layout options
Note: If the SmartObject has no alternate layouts, the Layout combo box is insensitive
You get this particular Instance Properties dialog box for the SmartDataViewer instance shown in Figure 66, displayed in the SmartContainer master layout.
In general, the Layout combo box lists the LayoutOptions property values available for the SmartObject instance. These are the alternate layout names that you define for the SmartObject when you create or edit the SmartObject in the AppBuilder using the Alternate Layout dialog box (Figure 62). If the SmartObject has a visualization for an alternate layout (such as Balance Information), you can make it visible for the instance by selecting the Layout value. Once you select and confirm the layout (by clicking on OK), the visualization for the selected layout appears in the SmartContainer design window for that SmartObject instance (Figure 67). Note the difference in the SmartDataViewer instance layout between Figure 66 and Figure 67.
Regardless of which layout you set for the SmartContainer, the SmartObject instance always displays the selected layout, as indicated by the ObjectLayout instance property setting shown in Figure 68. This is true at run time as well as at design time, unless you explicitly create a run‑time override of the instance layout. For more information on run‑time layout overrides, see the “Applying SmartObject layouts at run time” section.
If you leave the instance layout setting as [default], the instance in the design window has no layout property setting and displays the SmartObject master layout or the current layout of the SmartContainer, if different. This setting also allows you to specify the initial layout for the instance by the run‑time setting of the DefaultLayout property.
Applying SmartObject layouts at run time
You can reliably affect the layout of a SmartObject at run time in two ways:
*Set the SmartObject ObjectLayout property before SmartObject initialization and display, usually in a local version of the createObjects() event procedure.
*Set the SmartObject ObjectLayout property and apply it any time after SmartObject initialization.
Thus, you can set the initial SmartObject layout and change it as often as you like at run time.
Setting the initial layout
You can dynamically set the initial layout for your SmartObjects by creating a local createObjects() event procedure in the SmartContainer that parents the SmartObjects, as shown:
The code after the RUN SUPER statement is what you might add to the local createObjects() procedure. This code finds all of the SmartObjects in the SmartContainer (SmartObjects that have Container-Target links to this container). Next, it returns each link handle (the procedure handle for each SmartObject) and sets the ObjectLayout property for the associated SmartObject.
Note: Setting a property for a SmartObject that does not recognize the specified property has no effect. In this case, only SmartDataViewers and SmartDataBrowsers respond to the setting of ObjectLayout.
The p-layout identifier in this example represents a character‑string input parameter to the SmartContainer that holds the initial layout value. This assumes that the SmartContainer is called from some other procedure, perhaps with the actual p-layout value determined at run time.
Note that the initial setting of ObjectLayout occurs after the ADM createObjects() procedure executes. Thus, the SmartContainer changes all the SmartObject instance settings of ObjectLayout after the SmartContainer creates its SmartObjects but before it initializes them (using initializeObject()).
Changing layouts
You can change the layout of a SmartObject with multiple layouts at any time after initialization. For example, you might do this in a user interface trigger that explicitly changes the layout when the user clicks on a button, or in response to an expression value that determines what layout a particular user is permitted to see (for example, a security key). You might have a series of expressions in a CASE statement that sets a varying layout according to a variety of criteria.
In all of these cases you execute the following code, where so-handle is your SmartObject procedure handle and chosen-layout is the name that you have assigned to the alternate layout to be applied:
 
DYNAMIC-FUNCTION(’setObjectLayout’:U IN so-handle, chosen-layout).
RUN applyLayout IN so-handle.
Thus, for the Balance button shown in Figure 67, you can create a trigger like the following:
 
ON CHOOSE OF bBalance IN FRAME D-Dialog DO: /* Balance */
  DYNAMIC-FUNCTION(’setObjectLayout’:U IN h_v_cust, 
    "Balance Information":U).
  RUN applyLayout IN h_v_cust.
END.
Executing this code immediately redisplays the layout for the SmartObject specified by the h_v_cust handle. This code can execute anywhere inside or outside of the SmartObject as long as it occurs after SmartObject initialization and while the SmartObject is still instantiated.