April 23, 2013

New in Smart 1.1: Modal Dialogs

Besides the new compiler and a bunch of new components, Smart 1.1 also includes support for modal dialogs. There is also a new demo ModalDialog which shows how to use the new feature. Today I’ll walk you through this demo.

Please note that Smart 1.1 contains an RTL bug which makes the modal dialog functions unusable. You can easily fix it by editing one RTL file. The process is described in my post New in Smart 1.1: Bugs and Omissions.

Let’s start by running the application. The main form contains just a button and a memo control.

image

When you click on the Enter data button, a modal dialog is displayed, prompting you to enter a name and an address. The rest of the form is hidden behind an opaque layer which also makes it non-responsive to clicks and touches.

image

If you click on the + button, another modal dialog is be displayed. This one contains just a Close button and no other components. Everything behind this dialog is again hidden under an opaque layer.

image

By clicking the Close and then OK or Cancel buttons you’ll return to the main form.

Design

The application contains three forms. Main form (Form1; left part of the picture below) contains a button and a memo. The first modal dialog (DlgPersonalInfo; middle part of the picture) contains a few labels and edit boxes, a button to display the second modal dialog and two buttons to close the dialog. All these controls are placed on a single panel control (W3pnlDialog).

The second modal dialog (DlgSelectAddress; right part of the picture) contains just a panel (W3pnlDialog) and a button placed on this panel.

image

This arrangement of controls where everything is placed on a panel is not arbitrary. As of this moment, Smart only supports full-screen forms. As we want the original form to be displayed under the modal dialog, the RTL takes one panel from a “modal” form and displays it over the owner form. Every component that is not a child of the panel will be ignored in the process.

Code

Let’s see how all this is put together in the code. To display a model dialog, an application must call Application.ShowModal API. This method accepts six parameters:

  • The name of the form that contains the dialog (DlgPersonalInfo in the example below).
  • The name of the panel that will function as the main dialog element (W3pnlDialog). You can define multiple dialogs in the same form by designing them each in its own panel.
  • The name of the control that will receive focus when the dialog is displayed. You can leave this field empty (set to an empty string) which will cause all controls to be unfocused.
  • A method accepting a single parameter of type TW3CustomForm. This method is called before the dialog is displayed and can initialize controls in the dialog. When the method is called, the parameter will contain the form object containing the dialog panel (TDlgPersonalInfo in this case). (This also holds for the next two ShowModal parameters.)
  • A method accepting a single parameter of type TW3CustomForm. This method is called when the dialog is closed with the mrOK status.
  • A method accepting a single parameter of type TW3CustomForm. This method is called when the dialog is closed with the mrCancel status. This method is optional – if it is left out and the user cancels the dialog, nothing special will happen (besides the dialog disappearing, of course).

A modal dialog is always displayed centred over the owner form, regardless of the panel’s position in the designer.

procedure TForm1.AddLine(msg: string);
begin
W3Memo1.Text := W3Memo1.Text + msg + #13#10
;
end
;

procedure
TForm1.InitializeObject;
begin
inherited
;
{$I 'Form1:impl'}
W3Button1.OnClick :=
lambda
Application.ShowModal('DlgPersonalInfo', 'W3pnlDialog', 'W3inpName'
,
lambda
(dialog)
TDlgPersonalInfo(dialog).FullName := ''
;
TDlgPersonalInfo(dialog).Address := ''
;
end
,
lambda
(dialog)
AddLine('Name: ' +
TDlgPersonalInfo(dialog).FullName);
AddLine('Address: ' +
TDlgPersonalInfo(dialog).Address);
end
,
lambda
(dialog)
AddLine('Data entry was cancelled'
);
end
);
end
;
end
;




To close a dialog, application must call Application.HideModal with either a mrOK or mrCancel parameter.

procedure TDlgPersonalInfo.InitializeObject;
begin
inherited
;
{$I 'DlgPersonalInfo:impl'}
W3btnOK.OnClick := lambda Application.HideModal(mrOK); end
;
W3btnCancel.OnClick := lambda Application.HideModal(mrCancel); end
;
W3btnLookupAddress.OnClick
:=
lambda
Application.ShowModal('DlgSelectAddress', 'W3pnlDialog', '', nil
,
lambda
(dialog)
W3inpAddress.Text := 'selected'
;
end
);
end
;
end
;

You can test the ModalDialog demo at http://www.gabrijelcic.org/Smart/ModalDialog.

No comments:

Post a Comment