Please ensure Javascript is enabled for purposes of website accessibility
Powered by Zoomin Software. For more details please contactZoomin

AVEVA™ Engineering

Complex Form Layout

  • Last UpdatedApr 24, 2023
  • 6 minute read

The figure below illustrates Tabset frames, Text gadgets, Combobox, Lists, Text Panes, Paragraphs, and Buttons. Note that this is a fully functional, docking form which illustrates the use of form methods, particularly the Constructor method, and the use of open callbacks. It also demonstrates the use of the dock and anchor attributes of the gadget to achieve forms with intelligent resize behavior.

The file layout2.pmlfrm, shown below, defines the form.

Within the form definition the TABSET frame is defined and directly contains a frame gadget for each tabbed page. Note its ANCHOR ALL setting which maintains the distance between each edge of the frame and the corresponding edge of the form, when the form is resized by you. This allows the frame to grow and shrink without overwriting gadgets outside of it.

Each tabbed page frame contains the definition of all the gadgets belonging to the page.

Note:
The use of the DOCK FILL setting which allows each edge of the tabbed page frame to stick to the corresponding edge of the TABSET frame so that they grow and shrink in unison.

Alternatively, when you define a TABSET FRAME, you can specify its DOCK or ANCHOR attributes to determine its resize behavior within the form.

For each tabbed-page frame within the TABSET, it is no longer necessary to specify any DOCK or ANCHOR attribute settings, and any that are specified will be ignored. Each tabbed-page frame will always fill the available space in its TABSET parent (it exhibits DOCK FILL behavior).

The gadget ANCHOR attribute is used extensively to allow resizable gadgets to expand in specific directions and not others for. It is also used by non-resizable gadgets, e.g. BUTTONs, to allow them to move with edges of their containers and so avoid being overlaid by resizing gadgets.

Note also that the extensive use of form methods to provide the intelligence of the form as gadget callbacks. In particular, the method listCallback(!list is GADGET, !event is STRING), which just reports details of select and unselect events on list fields, has the standard form of an open callback, and is used as such on the list gadgets LI1 and LI2, !this.Li1.callback = |!this.listCallback(|.

Open callbacks are described in PML Open Callbacks.

-- PDMS customization User Guide

-- Form: layout2 - Demonstrate complex form layout

-- Extended for PDMS12.0 to illustrate ComboBox gadget

layout form !!layout2 dialog dock left VarChars NoAlign

title 'Form !!layout2'

-- define context menus:

-- for colour option gadget

!menu = !this.newmenu( 'ColourActions', 'POPUP' )

!menu.Add( 'CALLBACK', 'Add new colour', '!this.serviceMenu( ', 'AddColour' )

!menu.Add( 'TOGGLE' , 'Editable' , '!this.serviceMenu( ', 'ToggleEdit' )

!menu.Add( 'CALLBACK', 'Delete Colour', '!this.serviceMenu( ', 'DelColour' )

paragraph .Message width 40 lines 3

path DOWN

frame .Tabset TABSET 'tabset' anchor All

--Page 1-------------------------------------------------

frame .page1 |Page 1| dock Fill

frame .frame4 'Frame 4'

paragraph .Message4 text 'This is a ComboBox gadget' width 18

combobox .Colour tagwid 5 'Colour' scroll 20 width 5 tooltip'set/add colour for paragraph'

exit

frame .frame6 'Frame 6' width.frame4

halign right

paragraph .Message6 text 'These are right aligned text gadgets' width 16 lines 2

text .Width tagwid 5 'Width' width 5 is REAL

text .Height tagwid 5 'Height' width 5 is REAL

text .Area tagwid 5 'Area' width 5 is REAL

halign left

button .b3 |area| tooltip'calculate the area'

exit

frame .frame5 'Frame 5' at Xmax.frame4+2 Ymin.frame4 anchor All

paragraph .Message5 text 'This is a multi-choice list gadget' wid 12 lines 2

list .Li1 'Select some of these' anchor all MULTIPLE width 12 height 11

button .b1 |print| Anchor L + B tooltip'print list selections'

exit

exit

--Page 2-------------------------------------------------

frame .page2 |Page 2| at 0 0 dock Fill

frame .frame7 'Frame 7' anchor all width 20 height 13

--Force use of fixed width font

textpane .text 'Textpane: Fixed width font' FixChars dock Fill width 1 height 1

exit

frame .frame8 'Frame 8' at Xmax.frame7 ymin.frame7 anchor T+B+R wid.frame7 hei.frame7

path down

paragraph .Message8 text 'Multi-column, single-choice list' width 15 lines 2

list .li2 |Cars (zero-select)| anchor T+B+L+R columns single zerosel width 15 height 12

button .b2 |print| Anchor L + B tooltip'print list selection'

exit

exit

exit

path right

button .CANCEL at XMIN form YMAX form anchor L + B CANCEL

button .RESET anchor L + B RESET

button .OK at XMAX form-size anchor R+B OK

exit

define method .layout2()

$P************************

$P !!layout2 CONSTRUCTOR()

$P************************

-- CONSTRUCTOR - initialise gadget values

!this.firstShownCall = '!this.firstShown()'

-- main form gadgets

-- paragraph

!this.message.val = |Complex form layout

This shows a dockable, resizable form with tabbed page frames and use of the gadget Dock and Anchor attributes|

-- tooltips

!this.CANCEL.setTooltip('discard values and hide the form')

!this.RESET.setTooltip('reset to initial values')

!this.OK.setTooltip('accept values and hide the form')

--Page 1

-- frame 4

-- option

!ColourArray[1]='White'

!ColourArray[2]='Black'

!ColourArray[3]='Red'

!ColourArray[4]='Green'

!ColourArray[5]='Blue'

!This.Colour.Dtext=!ColourArray

-- set callback

!this.colour.callback = |!this.ServiceColourOption( |

-- assign context menu

!this.colour.setPopup(!this.ColourActions)

-- frame 5

-- multi-choice list

do !i from 1 to 20

!Elements[!i] = 'list element $!i'

enddo

!This.Li1.Dtext= !Elements

-- set callbacks

!this.b1.callback = |!this.printListSelections(!this.li1)|

!this.li1.callback = |!this.listCallback(|

-- frame 6

-- make Area read-only

!this.Area.seteditable( false )

!this.Width.val = 6.0

!this.Height.val = 3.5

!this.b3.callback = '!this.calcArea()'

!this.b3.background = 'pink'

--Page 2

-- frame 7

-- textpane - add data

!s[1] = 'Try editing the contents of this textpane gadget:='

!s[2] = | 1 2 3 4 5|

!s[3] = |12345678901234567890123456789012345678901234567890|

!s[4] = | 4 Ford Escort|

!s[5] = | 5 Ford Fiesta|

!s[6] = | 6 Vauxhall Nova|

!s[7] = | 7 Vauxhall Astra|

!s[8] = | 8 Vauxhall Lotus|

!s[9] = | 9 LandRover RangeRover £62000|

!s[10]= |10 LandRover Defender £23999|

do !i from 11 to 99

!s[!i] = '$!i--+---1---+---2---+---3---+---4---+----5'

enddo

!this.text.val = !s

-- frame 8

-- multi-column list

-- Define headings

!a[1] = 'Make'

!a[2] = 'Model'

!a[3] = ' Price'

!this.li2.setHeadings(!a)

-- set up dtext rows as array of array

!Row1[1] = 'Landrover'

!Row1[2] = 'RangeRover'

!Row1[3] = '£62000'

!Row2[1] = 'Landrover'

!Row2[2] = 'Defender'

!Row2[3] = '£23999'

!Row3[1] = 'Lancia'

!Row3[2] = 'Delta'

!Row3[3] = 'not for sale'

!Row4[1] = 'Fiat'

!Row4[2] = 'Tempra'

!Row4[3] = 'offers'

!Row5[1] = 'VW'

!Row5[2] = 'Golf GTi'

!Row5[3] = 'p.o.a.'

do !i from 1 to 5

!dtext[!i] = !Row$!i

enddo

!this.li2.setRows( !dtext )

-- Add data

do !i from 1 to !dtext.size()

!rtext[!i] = 'row $!i'

enddo

!this.li2.rtext = !rtext

-- set callbacks

!this.b2.callback = |!this.printListSelection(!this.li2)|

!this.li2.callback = |!this.listCallback(|

-- Initialise menus

!this.ColourActions.setFieldProperty('ToggleEdit', 'selected', true)

-- end of CONSTRUCTOR

endmethod

define method .firstShown()

$P************************

$P !!layout2.firstShown()

$P************************

-- carry out actions which need form to be shown

!this.message4.background = !this.Colour.selection('DTEXT')

endmethod

define method .listCallback(!list is GADGET, !event is STRING)

-- open callback to report on list events

-- can be used for any list gadget

!name = !list.fullname()

!n = !list.pickedField

if(!n gt 0) then

!sel = !list.dtext[!n]

$P $!event callback on field $!n<$!sel> for list $!name

endif

endmethod

define method .calcArea()

-- calculate the area

!area = !this.width.val * !this.height.val

!this.Area.val = !area

endmethod

define method .printListSelection(!list is GADGET)

-- report single-selection list gadget selection

-- can be used for any single-choice list

!sel = !list.selection('Dtext')

!num = !list.val

!name = !list.fullname()

$P -----------------------------------------------

$P selected field for list $!name

$P Field $!num: <$!sel>

$P -----------------------------------------------

endmethod

define method .printListSelections(!list is GADGET)

-- report multi-selection list gadget selections

-- can be used for any multi-choice list

!sels = !list.selection('Dtext')

!nums = !list.val

!name = !list.fullname()

!nvals = !sels.size()

$P -----------------------------------------------

$P $!nvals selected fields for list $!name

do !n from 1 to $!nvals

$P Field $!nums[$!n]: <$!sels[$!n]>

enddo

$P -----------------------------------------------

endmethod

define method .serviceMenu(!menu is MENU, !event is STRING )

-- Service selections on menu fields

!menuname = !menu.name()

!fieldname = !menu.pickedFieldname

-- $P $!event $!menuname > $!fieldname

if( !menuname eq 'ColourActions' ) then

if( !fieldname eq 'AddColour' ) then

if( !event eq 'SELECT' ) then

!this.ServiceColourOption(!this.Colour, 'VALIDATE')

endif

elseif(!fieldname eq 'ToggleEdit' ) then

!this.Colour.Editable = (!event eq 'SELECT')

elseif(!fieldname eq 'DelColour' ) then

!this.Colour.Clear(!this.Colour.displayText())

-- reselect in case its changed

!this.message4.background = !this.Colour.Selection('dtext')

handle (61,620)

return

endhandle

endif

endif

endmethod

define method .ServiceColourOption(!option is GADGET, !event is STRING)

-- Service Colour Option gadget

!name = !option.fullname()

--$P************************

--$P !!layout2.ServiceColourOption($!name, $!event)

--$P************************

if( !event eq 'VALIDATE' ) then

-- add new colour to list, without duplicates

!colnam = !option.displayText().trim()

$p $!name $!event $!colnam

!vals = !option.Dtext

do !i from 1 to !vals.size()

golabel /finished if( !vals[!i] eq !colnam )

enddo

-- try to use the colour, only add if valid

!this.message4.background = !colnam

handle (61,620)

return error 1 'Colour $!colnam is not in the Colour Table'

endhandle

--add to list and make current

!option.add(!colnam)

!option.select('DTEXT', !colnam)

--

label /finished

elseif( !event eq 'SELECT' ) then

-- change background colour of paragraph

!colnam = !this.colour.selection('dtext')

$p $!name $!event $!colnam

!this.message4.background = !colnam

elseif( !event eq 'UNSELECT' ) then

!fld = !this.colour.pickedField

!colnam = !this.colour.dtext[!fld]

$p $!name $!event $!colnam

endif

endmethod

Related Links
TitleResults for “How to create a CRG?”Also Available in