This section will take two dialogs and migrate them from their older version to using the Layout Manager.

Manage View Groups Dialog

The Manage View Groups dialog is already resizable. It contains a toolbar with 3 buttons at the top, a ListBox in the middle and a couple of buttons at the bottom. The only layout problem, according to the UI Guidelines, is that the buttons are centered in the dialog. So one goal is to move those buttons to the lower right hand corner. Other than that, the overall layout can remain the same.

Before Image

ViewGroups-Before.png

After Image

ViewGroups-After.png

For the overall layout, we'll use a VStackLayout. It allows you to add items from top to bottom. For the toolbar buttons at the top, we'll use a FlowLayout, and it will be the first item in the VStackLayout. We'll use the standard FLOWLAYOUTID_IconButtons FlowLayout definition, which is built into ustation.rsc. Notice the use of the AUTO_XYWH helper macro, which indicates the default size of the item will be used and the Layout Manager will determine the position.

The ListBox itself will be the second item. It needs no other layout container. We give it a stretch factor of 1 so it gets more space vertically as the dialog is resized larger.

The buttons at the bottom will be put into an HStackLayout, and a Stretch item will be placed at the beginning of it to push the buttons to the right. The Stretch item is given a stretch factor of 1 so it gets more space horizontally as the dialog is resized larger. We use the standard HSTACKLAYOUTID_DialogButtons HStackLayout definition, which is built into ustation.rsc. For standardization of margins and spacing, layouts defined in ustation.rsc should be used when possible.

This example uses the following common techniques:

Before

DialogBoxRsc DIALOGID_VIEWGROUP_ViewGroups =
{
DIALOG_LIST_W, DIALOG_H,
HOOKDIALOGID_VIEWGROUP_ViewGroups, NOPARENTID,
TXT_ViewGroupDialogTitle,
{
@if (FeatureAspect (PP_ID_FeatureAspects_View_ViewGroups_Create)) // @fadoc 'Create View Group' ...
{{ 0, 0, 0, 0}, IconCmd, ICONCMDID_VIEWGROUP_Create, ON, 0, "", ""},
@endif
@if (FeatureAspect (PP_ID_FeatureAspects_View_ViewGroups_Properties)) // @fadoc 'Edit View Group Properties' ...
{{ 0, 0, 0, 0}, IconCmd, ICONCMDID_VIEWGROUP_Properties, ON, 0, "", ""},
@endif
@if (FeatureAspect (PP_ID_FeatureAspects_View_ViewGroups_Delete)) // @fadoc 'Delete View Group' ...
{{ 0, 0, 0, 0}, IconCmd, ICONCMDID_VIEWGROUP_Delete, ON, 0, "", ""},
@endif
{{ PANEL_ITEM_X, VIEWGROUP_LIST_Y, VIEWGROUP_LIST_WIDTH, 0},
ListBox, LISTID_VIEWGROUP_ViewGroups, ON, 0, "", ""},
{{ RIGHT_CENTER_BUTTON_X, PANEL_ITEM_ROW_AFTER_LIST(1), BUTTON_STDWIDTH*2, 0},
PushButton, PUSHBUTTONID_VIEWGROUP_Apply, ON, 0,"", ""},
{{ LEFT_CENTER_BUTTON_X, PANEL_ITEM_ROW_AFTER_LIST(1), BUTTON_STDWIDTH*2,0},
PushButton, PUSHBUTTONID_VIEWGROUP_Close, ON, 0, "", ""},
}
};

After

From usation.rsc

(.unparsed)
// Used for Icon Buttons in a FlowLayout resembling a Toolbar at the top or bottom of a dialog
FlowLayoutRsc FLOWLAYOUTID_IconButtons =
{
{1, 1, 1, 1}, // Margins - Left, Top, Right, Bottom
1, 1 // HSpacing, VSpacing
};
// Used for OK/Cancel buttons at the bottom of a dialog
HStackLayoutRsc HSTACKLAYOUTID_DialogButtons =
{
{XC_3_2, XC_3_2, XC_3_2, XC_3_2}, // Margins - Left, Top, Right, Bottom
XC_3_2 // Spacing
};

From view group code

(.unparsed)
DialogBoxRsc DIALOGID_VIEWGROUP_ViewGroups =
{
DIALOG_LIST_W, DIALOG_H,
HOOKDIALOGID_VIEWGROUP_ViewGroups, NOPARENTID,
TXT_ViewGroupDialogTitle,
{
BEGIN_FLOW_LAYOUT (FLOWLAYOUTID_IconButtons, "")
@if (FeatureAspect (PP_ID_FeatureAspects_View_ViewGroups_Create)) // @fadoc 'Create View Group' ...
{AUTO_XYWH, IconCmd, ICONCMDID_VIEWGROUP_Create, NO_ITEMARGS},
@endif
@if (FeatureAspect (PP_ID_FeatureAspects_View_ViewGroups_Properties)) // @fadoc 'Edit View Group Properties' ...
{AUTO_XYWH, IconCmd, ICONCMDID_VIEWGROUP_Properties, NO_ITEMARGS},
@endif
@if (FeatureAspect (PP_ID_FeatureAspects_View_ViewGroups_Delete)) // @fadoc 'Delete View Group' ...
{AUTO_XYWH, IconCmd, ICONCMDID_VIEWGROUP_Delete, NO_ITEMARGS},
@endif
{{ AUTO_XY, VIEWGROUP_LIST_WIDTH, 0}, ListBox, LISTID_VIEWGROUP_ViewGroups, NO_ITEMARGS},
BEGIN_HSTACK_LAYOUT(HSTACKLAYOUTID_DialogButtons, "")
{{ AUTO_XY, BUTTON_LARGEWIDTH, 0}, PushButton, PUSHBUTTONID_VIEWGROUP_Apply, NO_ITEMARGS},
{{ AUTO_XY, BUTTON_LARGEWIDTH, 0}, PushButton, PUSHBUTTONID_VIEWGROUP_Close, NO_ITEMARGS},
}
};

Tool Boxes Dialog

The ToolBoxes dialog was not resizable before. So one goal is to make it resizable. The old version of the dialog has quite a bit of wasted space, as well. So another goal is to move some of the items to new locations in order to give more space to the ListBox, which is the main item on this dialog. The old dialog had an OptionButton above the ListBox, 3 Toggles below the ListBox and Remove and Customize buttons to the right of the ListBox. So we'll put all of those items to the right of the ListBox, which will help give it more space. Another goal is to move the OK and Cancels buttons to the lower right hand corner to adhere to the UI Guidelines.

Before Image

ToolBoxes-Dialog-Before.png

After Image

ToolBoxes-Dialog-After.png

To make an MDL dialog resizable, we add the DIALOGATTR_GROWABLE attribute to the list of dialog attributes. We start the layout of the dialog with a VStackLayout. The ListBox will now be placed in the upper left hand corner of the dialog, and the settings and other buttons will be placed to the right of the ListBox. In order to achieve this, we place an HStackLayout as the first item in the VStackLayout and place the ListBox as the first item of the HStackLayout. We give both the HStackLayout and the ListBox a stretch factor of 1 so they get more space horizontally and vertically as the dialog is resized larger. We set the minimum size for the ListBox in its resource definition using the EXTINTATTR_MINWIDTH and EXTINTATTR_MINHEIGHT extended attributes (shown above - Set the Minimum Size for a ListBox.

Since we want several items to be at the right of the ListBox, we can group those in a VStackLayout by adding each item with appropriate spacing between using the SPACING helper macro. At the end of the VStackLayout, we add a STRETCH(1) to prevent the items in the VStackLayout from expanding vertically. We add the VStackLayout containing the settings and buttons to the HStackLayout after some space.

The OK and Cancel buttons at the bottom are put into an HStackLayout, and a Stretch item will be placed at the beginning of it to push the buttons to the right. The Stretch item is given a stretch factor of 1 so it gets more space horizontally as the dialog is resized larger. As with the "Managed View Groups" dialog, we use the standard HSTACKLAYOUTID_DialogButtons HStackLayout definition, which is built into ustation.rsc. For standardization of margins and spacing, layouts defined in ustation.rsc should be used when possible.

Several of the older helper macros dealing with column position and row calculations could be removed after migrating to the Layout Manager.

This example uses the following common techniques:

Before

(.uparsed)
#define X1 (1*XC) // text & option button x position
#define X2 (2.5*XC)
#define X3 (XSIZE/2)
#define X4 (3.5*XC)
#define Y1 (GENY(1))
#define YGBOX (Y1+YC/2)
#define YLBOX (YGBOX+YC)
#define YLABEL (GENY(12))
#define Y2 (Y1+2*YC)
#define Y3 (Y2+3*YC)
#define Y4 (Y3+2*YC)
#define Y5 (Y4+2*YC)
#define Y6 (Y5+3*YC)
#define YSEP (GENY(12) + 1.5*YC) // Microsoft Standard says 10 pixels below list box
#define SEP_WIDTH (XSIZE - 2*X1)
#define GBOX_HEIGHT (YLABEL+(1.5*YC)-YGBOX)
#define GBOX_WIDTH (XBUT-35+XC)
#define YTOGGLE1 (YSEP + 10)
#define YTOGGLE2 (YTOGGLE1 + YC+BGAP)
#define YTOGGLE3 (YTOGGLE2 + YC+BGAP)
#define XBUT (X2+32*XC+ 35) // Microsoft standard says 35 pixels from the right margin of the list box
#define BUTTON_WIDTH (BUTTON_STDWIDTH + 10*XC)
DialogBoxRsc DIALOGID_OpenToolBox =
{
XSIZE, YSIZE,
NOHELP, MHELP, HOOKID_Dialog_OpenToolBox, NOPARENTID,
TXT_OpenToolBoxTitle,
{
{{X2,YLBOX,0,0}, ListBox, LISTBOXID_ToolBoxes, ON, 0, "", ""},
{{X2,Y1,0,0}, OptionButton, OPTIONBUTTONID_ListType, ON, 0, "", ""},
{{X2,YLABEL,0,0}, Label, 0, ON, LABEL_FONT_BOLD, TXT_Label_FramesBold, ""},
{{XBUT, Y1,BUTTON_WIDTH,0}, PushButton, PUSHBUTTONID_OK, ON, 0,"", ""},
{{XBUT, Y2,BUTTON_WIDTH,0}, PushButton, PUSHBUTTONID_Cancel, ON, 0, "", ""},
{{XBUT, Y3,BUTTON_WIDTH,0}, PushButton, PUSHBTNID_Reset, ON, 0, "", ""},
{{XBUT, Y4,BUTTON_WIDTH,0}, PushButton, PUSHBTNID_Customize, ON, 0, "", ""},
{{X1, YSEP, SEP_WIDTH,0}, Separator, 0, ON, 0, "", ""},
{{X1, YTOGGLE1, 0,0}, ToggleButton, TOGGLEBTNID_LargeBtns, ON, 0, "", ""},
{{X1, YTOGGLE2, 0,0}, ToggleButton, TOGGLEBTNID_ToolTips, ON, 0, "", ""},
{{X1, YTOGGLE3, 0,0}, ToggleButton, TOGGLEBTNID_ImmediatelyOpen, ON, 0, "", ""},
}
};

After

(.unparsed)
#define XSIZE (100*XC)
#define YSIZE (30*YC)
#define BUTTON_WIDTH BUTTON_LARGEWIDTH
{
{0, 0, 0, 0},
YC/3
};
DialogBoxRsc DIALOGID_OpenToolBox =
{
XSIZE, YSIZE,
NOHELP, MHELP, HOOKID_Dialog_OpenToolBox, NOPARENTID,
TXT_OpenToolBoxTitle,
{
BEGIN_HSTACK_LAYOUT(HSTACKLAYOUTID_DialogButtons, "stretch='1'")
{AUTO_XYWH, ListBox, LISTBOXID_ToolBoxes, ON, 0, "", "stretch='1'"},
{AUTO_XYWH, OptionButton, OPTIONBUTTONID_ListType, ON, 0, "", ""},
{AUTO_XYWH, ToggleButton, TOGGLEBTNID_LargeBtns, ON, 0, "", ""},
{AUTO_XYWH, ToggleButton, TOGGLEBTNID_ToolTips, ON, 0, "", ""},
{AUTO_XYWH, ToggleButton, TOGGLEBTNID_ImmediatelyOpen, ON, 0, "", ""},
{{AUTO_XY,BUTTON_WIDTH,0}, PushButton, PUSHBTNID_Reset, ON, 0, "", ""},
{{AUTO_XY,BUTTON_WIDTH,0}, PushButton, PUSHBTNID_Customize, ON, 0, "", ""},
BEGIN_HSTACK_LAYOUT(HSTACKLAYOUTID_DialogButtons, "")
{{AUTO_XY,BUTTON_WIDTH,0}, PushButton, PUSHBUTTONID_OK, ON, 0,"", ""},
{{AUTO_XY,BUTTON_WIDTH,0}, PushButton, PUSHBUTTONID_Cancel, ON, 0, "", ""},
}};

Copyright © 2017 Bentley Systems, Incorporated. All rights reserved.