Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

@Layout

Describes the layout of a screen or report: Label, Input, Column, DataGridView, Block, or any other Name(...) as a generic control. Control names may carry @ optionally (@Label/Label are equivalent).

Controls with their own grammar

ControlSyntaxValid inDescription
LabelLabel(x, y, text[, Style(...)]...)Program, ScreenStatic label at x,y. text can be &Variable, &variable.member (a struct path), "literal" or a bare field name. x,y = 1,1 (exact corner) is forbidden — DDS rejects any field there. Style(...) (Screen only) gives it color and attributes; see Style.
BlockBlock("Name")[ Label(...), ... ]ProgramA named, printable group of Labels — an instance is printed with Print("Name") from @Source.
InputInput("Name", x, y, text, &Variable[, enabled][, Style(...)]...)ScreenEditable field at x,y. "Name" identifies the control (read with CurrentInput()). &Variable (or a &variable.member path) is where the entered value is stored. enabled optional (default true): a literal, &Variable (or a &variable.member path), a Function() returning number (non-zero = enabled) or a full condition, re-evaluated before every redraw. x,y = 1,1 is also forbidden.
ColumnColumn(text, variableOrField[, Input|Hidden][, Style(...)]...)inside DataGridView onlyvariableOrField also accepts a &variable.member path. The optional 3rd argument makes the column editable (Input) or invisible (Hidden). Style(...) gives it color and attributes, evaluated per row; see Style in Column.
DataGridViewDataGridView("Name", x, y, rows[, separator])[ Column(...), ... ]ScreenA named grid at x,y showing rows visible rows. The name is required and unique among Input/DataGridView controls. See DataGridView for the full guide.

Example (Screen)

@Layout {
    @Label(1,2,&Program)
    @Label(1,70,&MyDate)
    @Input("txtRequestNo",3,1,"Request No.: ",&RequestNo,true)
    @DataGridView("GridRequests",6,1,8," ") [
        @Column("Country",&nCountry)
        @Column("User",&cUser)
    ]
}

Struct members in the layout

Label, Input (target variable and enabled) and Column accept struct member paths, including nested ones: &cust.Code, &ord.Cust.Name. They also work with Print in a Program.

@Layout {
    @Label(1,2,&cust.Code)
    @Input("TxtName",3,2,"Name:",&cust.Name,&cust.Active)
    @Input("TxtCust",4,2,"Customer:",&ord.Cust.Name)
    @DataGridView("GridRows",6,1,8," ") [
        @Column("Name",&row.Name)
    ]
}

Each path becomes a DDS field: every . is replaced by _, the result is uppercased and truncated to 10 characters (cust.Code -> CUST_CODE, ord.Cust.Name -> ORD_CUST_N). If two variables or paths end up with the same DDS name (for example cust.Code and cust_Code), E00210 is reported. A member that does not exist reports E00178.

Upper and lower case in text Input

An Input whose variable is char or varchar accepts lowercase: the DDS carries CHECK(LC), so the 5250 terminal no longer converts what is typed to uppercase. The program receives exactly what the user typed (for example Lima). Numeric, date and time Input fields are unchanged.

When comparing the typed value against literals, normalize it with Upper:

If Upper(&City) = "LIMA"
    ...
EndIf

Full conditions

The optional last parameter enabled of Input (and the optional condition of Style) accepts, besides the true/false literal, these forms:

  • &Variable: non-zero = enabled.
  • Function(): a function with no arguments returning number; non-zero = enabled.
  • A full condition: comparisons (= <> < <= > >=), And, Or, Not, numbers, strings, variables and Function() calls with no arguments. It is true when it holds.
@Input("TxtOp",7,2,"Operation:",&Op, Not &Locked = 1 And &Status <> "9")

The condition is re-evaluated before every redraw, using the same indicator mechanism that dynamic enabling already used. Precedence: see Not.

Table fields on their own, indexes and methods are not allowed in the condition: they report E00322.

Style: screen color and attributes

Style(...) goes at the end of the parameters of a Label, an Input or a DataGridView Column, and is only valid in a Screen (in any other object type it gives E00325). It assigns 5250 screen color and attributes (DDS COLOR and DSPATR).

Label(x, y, text, Style(...)[, Style(...)])
Input("Name", x, y, text, &Var[, enabled][, Style(...)]...)
Column(text, &Var[, Input|Hidden][, Style(...)]...)

Syntax: Style(Name, Name, ...[, condition]).

Colors (at most one per Style; otherwise E00321):

NameDDS
GreenCOLOR(GRN)
WhiteCOLOR(WHT)
RedCOLOR(RED)
BlueCOLOR(BLU)
YellowCOLOR(YLW)
PinkCOLOR(PNK)
TurquoiseCOLOR(TRQ)

Attributes (combinable with each other and with a color):

NameDDSEffect
ReverseDSPATR(RI)Reverse video.
HighDSPATR(HI)High intensity.
UnderlineDSPATR(UL)Underline.
BlinkDSPATR(BL)Blink.
HiddenDSPATR(ND)Typed text is not displayed (hidden field).

An unknown name gives E00320. A Style with no color or attribute gives E00324.

Equivalences for those migrating: 'RI' = Reverse, '+' = High, MGN = Pink.

Conditional Style

The last argument of a Style can be a condition, with the same forms as enabled (variable, Function() or full condition). The Style applies while the condition is true.

Rules per element:

  • At most one Style without a condition (the “normal” one): it applies only if no conditional Style is active.
  • Up to three conditional Style entries. Exceeding the limits gives E00323.
  • If two conditional Style entries hold at once, the first one declared wins.
  • Each conditional Style consumes one indicator from the same range as dynamic enabling (30-89).
  • A monochrome screen ignores COLOR.
@Layout {
    Label(1,2,&Title,Style(Reverse,High))
    Label(3,2,"F3=Exit",Style(Red))
    Label(5,2,&Desc,Style(Blue,&Status = "1" Or &Status = "2"),Style(Pink,&Status = "3"),Style(Green))
    Input("TxtOp",7,2,"Operation:",&Op,Not &Locked = 1 And &Status <> "9",Style(Yellow,Underline))
    Input("TxtAmt",8,2,"Amount:",&Amount,&Locked = 0,Style(Turquoise,&Locked = 1))
}

For &Desc, the text is blue if &Status is "1" or "2", pink if it is "3" and green otherwise. Full example: example/screens/SSTYLE01.warp.

Style in DataGridView Column

Column accepts Style(...) after the optional mode (Input/Hidden). The rules are the same (colors, attributes, at most one Style without a condition and three with a condition per column, the first one declared wins, errors E00320-E00324):

DataGridView("GridOrd",2,2,10)
[
    Column("Order",&VOrdNo)
    Column("Quantity",&VQty,Style(Red,High,&VQty > 100),Style(Green))
]

Key difference: the condition of a column Style is evaluated per row, at the time of LoadRow() (right before the row is stored in the subfile), with the values the variables hold at that instant. Therefore LoadRow() must come after the row variables are assigned. The indicators are stored together with each row, so the color of a row does not change if the variables change later. These indicators share the 30-89 range with the rest of Style and with enabled. Full example: example/screens/SJNGRD01.warp.

Limitations

  • Per-row dynamic enabling in the DataGridView (a conditional Column(..., Input)) does not exist yet (planned).

Example (Program, with a printable Block)

@Layout {
    @Block("Header") [
        Label(1,1,"Sales Report")
        Label(2,1,&Today)
    ]
}
@Source {
    Print("Header")
}

@Layout is optional in Program (a purely batch program, with no printed output, doesn’t need it) but required in Screen. Doesn’t apply to tables.