DlgAreaU Class

The DlgAreaU class is a subclass of the DlgArea class that assists the creation of dynamically resizable Dialogs. This class provides assistance in resizing and / or positioning controls when a dialog is resized. When the DlgArea and DlgAreaU classes are used together, the they provide a convenient way to create resizable dialogs.

To use objects of the DlgAreaU class include this line in your code:

::requires "OODIALOG.CLS"

Init

>>- aDlgAreaU~Init(Dialog--+--------------------------+--------+-)--><
                           +--,--Margin-+             |        |
                           +--,---------+--,-NoResize-+        |
                           +--,---------+--,----------+-NoMove-+

The DlgAreaU object creates a dialog area coterminous with the calling dialog. It inherits all the methods and attributes of the DlgArea Class (listed above).

Arguments:

The arguments you pass to the new method when creating a DlgArea Object are:

Dialog

An Object that is SubClassed from A UserDialog.

Margin

See DlgArea Margin.

NoResize

A set of Dialog Ids of widgets not to be resized during a resize.

NoMove

A set of Dialog Ids of widgets not to be moved during a resize.

CorrectionFactor

>>--ADlgAreaU~CorrectionFactor----------------------------------------><

An attribute containing the value used to adjust the ratio of the top & left margins to the bottom & right margins. (The default correction factor is set to 1.05.) See the Possible Problems section for some additional detail.

LastError

>>--ADlgAreaU~LastError-----------------------------------------------><

An attribute holding the details if an error was encountered when parsing the calling dialog's DefineDialog method. The value of the attribute is .nil if no error occurred.

NoMove

>>--ADlgAreaU~NoMove--------------------------------------------------><

An attribute holding the set of Dialog Ids of widgets not to be moved during a resize event.

NoResize

>>--ADlgAreaU~NoResize------------------------------------------------><

An attribute holding the set of Dialog Ids of widgets not to be resized during a resize event.

Creating Resizeable Dialogs

You can use the DlgAreaU Object to facilitate in creating dynamically resizable Dialog objects, but to do so you must carefully satisfy all the requirements below.

The Dialog must be created with the ThickFrame option. It may be created with the UserDialog Create method or CreateCenter method.

Your Dialog init method must include the line:

self~connectResize("OnResize")

Your DefineDialog method must start with these lines:

expose u
u = .dlgAreaU~new(self)          /* whole dlg   */

Your DefineDialog method must not reference variables within the Add Method parameters, although you can use references to DlgArea attributes, so

Self~addButton(23,1,5,6,"MyButton","Pressed")
self~addButton(14,b~x,b~y("10%"),b~w,b~h("9%"),"Button" 1,"Button"||1)

Both are OK, whereas

/* Seven buttons evenly spaced at 10% intervals, 9% high                     */
do i = 0 to 6
   self~addButton(12+i,b~x,b~y((i * 10)||"%"),b~w,b~h("9%"),"Button" i,"Button"||i)
end /* DO */

would now fail as the variable i is referenced within the parameters.

To debug your DlgAreaU call/insert the following after the instantiation

if u~lastError \= .nil then call errorDialog u~lastError

You must also include the following in your code.

/* ------------------------------------------------------------------------- */
::method OnResize
/* ------------------------------------------------------------------------- */
expose u
if u~lastError \= .nil then call errorDialog u~lastError
use arg dummy,sizeinfo
                                 /* wait for last size event msg then resize */
if self~PeekDialogMessage~left(8) \= "OnResize" then u~resize(self,sizeinfo)

The DlgAreaU method will then automatically resize & place the following widgets in your dialog when the dialog frame is dragged or the minimize, maximise or restore buttons are pressed:

Table 10-6. DlgAreaU Automatic Resize Elements

BLACKFRAMEBLACKRECTBITMAPBUTTONBUTTON
CHECKBOXCOMBOBOXENTRYLINEGRAYFRAME
GRAYRECTGROUPBOXLISTBOXLISTCONTROL
PASSWORDLINEPROGRESSBARRADIOBUTTONSCROLLBAR
SLIDERCONTROLTABCONTROLTEXTTREECONTROL
WHITEFRAMEWHITERECT  

The following widgets can be defined in a UserDialog, but cannot be handled by the DlgAreaU resize method, so should not be used.

Table 10-7. DlgAreaU Non-Automatic Resize Elements

BUTTONGROUPCHECKBOXSTEMCHECKGROUPCOMBOINPUT
FULLSEQINPUTINPUTGROUPINPUTSTEM
OKCANCEL...RADIOGROUPRADIOSTEM 

All of these widgets can be achieved using combinations of the permitted methods.

Possible Problems

The DlgAreaU resize method can create slightly over-size margins on the left & bottom of the Dialog. To correct for this the DlgAreaU class has a CorrectionFactor attribute set by default to 1.05. In tests, this correction factor appears to neutralise the effect. If your dialogs have over (or under) sized margins, you may be able to correct this in your code by adjusting the Correction Factor. For example:

U=.DlgAreaU~new(self)
U~CorrectionFactor=1.07

You will have to experiment to find the apropriate setting for this attribute.

Sample Code

/* DlgAreaDemo.Rex  --  Demonstrate DlgArea & DlgAreaU Classes  --  Feb 2006 */

MyDlg=.MyDialog~new
MyDlg~execute("ShowTop")
MyDlg~DeInstall

exit
::requires "OODWIN32.CLS"
/* ========================================================================= */
::class MyDialog Subclass UserDialog
/* ========================================================================= */
::method Init
/* ------------------------------------------------------------------------- */
  self~Init:super
  rc=self~CreateCenter(250,250,"MyDialog","ThickFrame", ,"MS Sans Serif",8)
  self~InitCode=(rc=0)
  self~connectResize("OnResize")

/* ------------------------------------------------------------------------- */
::method DefineDialog
/* ------------------------------------------------------------------------- */
expose u

u=.dlgAreaU~new(self)                                         /* whole dlg   */
if u~lastError \= .nil then call errorDialog u~lastError
e=.dlgArea~new(u~x       ,u~y       ,u~w("70%"),u~h("90%"))   /* edit   area */
s=.dlgArea~new(u~x       ,u~y("90%"),u~w("70%"),u~hr      )   /* status area */
b=.dlgArea~new(u~x("70%"),u~y       ,u~wr      ,u~hr      )   /* button area */

self~addEntryLine(12,"text",e~x,e~y,e~w,e~h,"multiline")
self~addText(s~x,s~y,s~w,s~h,"Status info appears here", ,11)

self~addButton(13,b~x,b~y("00%"),b~w,b~h("9%"),"Button" 0,"Button"||0)
self~addButton(14,b~x,b~y("10%"),b~w,b~h("9%"),"Button" 1,"Button"||1)
self~addButton(15,b~x,b~y("20%"),b~w,b~h("9%"),"Button" 2,"Button"||2)
self~addButton(16,b~x,b~y("30%"),b~w,b~h("9%"),"Button" 3,"Button"||3)
self~addButton(17,b~x,b~y("40%"),b~w,b~h("9%"),"Button" 4,"Button"||4)
self~addButton(18,b~x,b~y("50%"),b~w,b~h("9%"),"Button" 5,"Button"||5)
self~addButton(19,b~x,b~y("60%"),b~w,b~h("9%"),"Button" 6,"Button"||6)
self~addButton( 1,b~x,b~y("90%"),b~w,b~h("9%"),"Ok","Ok","DEFAULT")

/* ------------------------------------------------------------------------- */
::method Unknown
/* ------------------------------------------------------------------------- */
use arg msgname, args
StatusLine = Self~GetStaticControl(11)
StatusLine~SetTitle("You Pressed" msgname)

/* ------------------------------------------------------------------------- */
::method OnResize
/* ------------------------------------------------------------------------- */
expose u
use arg dummy,sizeinfo
                                 /* wait for last size event msg then resize */
if self~PeekDialogMessage~left(8) \= "OnResize" then u~resize(self,sizeinfo)

This achieves the same dialog as the previous DlgArea example, but now it is resizable by dragging the frame.