Builders
Builders are utility programs that work on objects in the Form and Class Designers. They can be anything from a simple property manipulators to complex object setup utilities.
07-Jun-04 Click here for the Europa Anchor builder
Here is the simplest general purpose builder:
* mybuild.prg lparameter lcCommand local i, n, laObjects[1] lcCommand = "laObjects[i]." + lcCommand n = aselobj( laObjects ) && all selected objects for i = 1 to n &lcCommand endfor
To use it select the objects you want to manipulate and in the command window do something like:
mybuild( "FontName = [Arial]" ) | set the font of all the objects to Arial |
mybuild( "ForeColor = 255" ) | set the objects to red |
Here's a builder that was needed in VFP3 to horizontally center more that one controls. In VFP5 the layout toolbar now provides this functionality. To use this builder select the controls to center and in the command window type: hcenter()
* hcenter.prg 21-Oct-96 * Usage: select object(s) to be horizontally centered within their container * in the command window enter =hcenter() * Copyright 1996, DF Software Development, Inc. local n, laObjects[1] n = aselobj( laObjects ) && all selected objects if ( n = 0 ) * nothing to do wait window "Select one or more controls to center horizontally" nowait return endif local i, loParent, lnMinX, lnMaxX, lnAdjustX * find the container object loParent = laObjects[1].Parent if ( loParent.BaseClass == "Page" ) * if it's a page go on up to the pageframe loParent = loParent.Parent endif * determine the X limits of the selected objects lnMinX = 999999 lnMaxX = -999999 for i = 1 to n with laObjects[i] lnMinX = min( lnMinX, .Left ) lnMaxX = max( lnMaxX, .Left + .Width ) endwith endfor * number of X pixels to shift each object if ( loParent.BaseClass == "Pageframe" ) lnAdjustX = lnMinX - ( loParent.PageWidth - ( lnMaxX - lnMinX ) ) / 2 else lnAdjustX = lnMinX - ( loParent.Width - ( lnMaxX - lnMinX ) ) / 2 endif * move each object for i = 1 to n with laObjects[i] .Left = .Left - lnAdjustX endwith endfor
The parallel builder for vertical centering:
* vcenter.prg 21-Oct-96 * Usage: select object(s) to be vertically centered within their container * in the command window enter =vcenter() * Copyright 1996, DF Software Development, Inc. local n, laObjects[1] n = aselobj( laObjects ) && all selected objects if ( n = 0 ) * nothing to do wait window "Select one or more controls to center vertically" nowait return endif local i, loParent, lnMinY, lnMaxY, lnAdjustY * find the container object loParent = laObjects[1].Parent if ( loParent.BaseClass == "Page" ) * if it's a page go on up to the pageframe loParent = loParent.Parent endif * determine the Y limits of the selected objects lnMinY = 999999 lnMaxY = -999999 for i = 1 to n with laObjects[i] lnMinY = min( lnMinY, .Top ) lnMaxY = max( lnMaxY, .Top + .Height ) endwith endfor * number of Y pixels to shift each object if ( loParent.BaseClass == "Pageframe" ) lnAdjustY = lnMinY - ( loParent.PageHeight - ( lnMaxY - lnMinY ) ) / 2 else lnAdjustY = lnMinY - ( loParent.Height - ( lnMaxY - lnMinY ) ) / 2 endif * move each object for i = 1 to n with laObjects[i] .Top = .Top - lnAdjustY endwith endfor
New Updated 15-Aug-97
Here are two builders that provide a nice feature still missing from the VFP5 and VFP3 layout toolbars. The VFP5 designer Format menu includes a Horizontal/Vertical Spacing item but it works slightly different that the functions here. These builders take a group of 3 or more controls and equispace them horizontally or vertically by distributing the controls within the space limits assigned to the controls. That is they put the same amount of space between the controls. To use these builders put one control at the left (top) edge of the area, put the last control at the right (bottom) edge, select all the controls to position and in the command window type: hequispace() or vequispace(). The code looks a lot like the above code for hcenter().
* hequispace.prg 15-Aug-97 * Usage: select object(s) to be horizontally equispaced within their limits * in the command window enter =hequispace() * Copyright 1997, DF Software Development, Inc. PARAMETERS uP1, uP2, uP3 && builders get sent 3 parameters by builder.app local n, laObjects[1] n = aselobj( laObjects ) && all selected objects if ( n < 3 ) * nothing to do wait window "Select three or more controls to horizontally equispace" nowait return endif local i, lnMinX, lnMaxX, lnAdjustX, lnTotalWidth * determine the X limits of the selected objects lnMinX = 999999 lnMaxX = -999999 lnTotalWidth = 0 for i = 1 to n with laObjects[i] lnMinX = min( lnMinX, .Left ) lnMaxX = max( lnMaxX, .Left + .Width ) lnTotalWidth = lnTotalWidth + .Width endwith endfor * number of X pixels between each object lnAdjustX = ( lnMaxX - lnMinX - lnTotalWidth ) / ( n - 1 ) * move objects 2..n-1 for i = 2 to n - 1 with laObjects[i] .Left = laObjects[i-1].Left + laObjects[i-1].Width + lnAdjustX endwith endfor
And the parallel vequispace:
* vequispace.prg 15-Aug-97 * Usage: select object(s) to be vertically equispaced within their limits * in the command window enter =vequispace() * Copyright 1997, DF Software Development, Inc. PARAMETERS uP1, uP2, uP3 && builders get sent 3 parameters by builder.app local n, laObjects[1] n = aselobj( laObjects ) && all selected objects if ( n < 3 ) * nothing to do wait window "Select three or more controls to vertically equispace" nowait return endif local i, lnMinY, lnMaxY, lnAdjustY, lnTotalHeight * determine the Y limits of the selected objects lnMinY = 999999 lnMaxY = -999999 lnTotalHeight = 0 for i = 1 to n with laObjects[i] lnMinY = min( lnMinY, .Top ) lnMaxY = max( lnMaxY, .Top + .Height ) lnTotalHeight = lnTotalHeight + .Height endwith endfor * number of Y pixels between each object lnAdjustY = ( lnMaxY - lnMinY - lnTotalHeight ) / ( n - 1 ) * move objects 2..n-1 for i = 2 to n - 1 with laObjects[i] .Top = laObjects[i-1].Top + laObjects[i-1].Height + lnAdjustY endwith endfor
Maybe you noticed the PARAMETERS statement in the builders, but the parms are not used anywhere. The reason for this is because these builders can be attached to the VFP BUILDER.APP program that is called when you select Builder... from the context menu in the Form/Class designer. The open architecture of the VFP builder allows our own builders to be easily added to the system. All that needs to be done is to "register" the builders in the \WIZARDS\BUILDER.DBF. Here's how to do this from the command window:
use home()+"wizards\builder.dbf" insert into builder values ("Horizontal Equispacer", ; "Put the same amount of horizontal space between selected objects", ; "", "MULTISELECT", "hequispace.prg", "", "", "" ) insert into builder values ("Vertical Equispacer", ; "Put the same amount of vertical space between selected objects", ; "", "MULTISELECT", "vequispace.prg", "", "", "" ) use
The value MULTISELECT means that these builders are only to be used when more than one object is selected. Although these builders require 3 or more objects are selected. Now when you select the controls you can access these builders via the context menu instead of using the command window.
Here's a couple of relevant KB Articles Q138979, Q141797 and Q147787