[Top] | [Contents] | [Index] | [ ? ] |
This document describes the M-Language (ML). The M-Language is a notation for describing menu-directed user interfaces which are to be displayed on small LCD-panels (16x4 or 20x4). ML independently describes a) menu hierarchy and b) the contents of each menu line. The menu line contents can be constructed by using many different building blocks, e.g. strings, integer i/o-fields, switches, options, soft functions keys flexible horizontal whitespace and many more. ML was designed to fit the needs for embedded system design. A compiler for ML written in Python generates a block of tagged binary data which is self-containing and can easily be included into ones own embedded application. See section `Introduction' in MEX - The Menu Executor.
Copyright (C) 1997-2004 Hubert Hoegl
Edition 0.9.1 Last change: 2004-05-24
1. Document History 2. Introduction 3. Elements of ML 4. The Portable-Menu-Format (Portable Menu Format) 5. An example menu specification
* Changed float format in mel.txi (added min, max, step fields).
2.1 Why menus? 2.2 General concept 2.3 Some commonly used notions 2.4 Structure of this document
In many cases a hierarchical ordering of information from general to exact description can improve the readability of complex information. The menu-based user interface, which is realized in many past and present computer systems (examples are the Atari Desktop, the DOS SAA user-interface and of course all modern graphical user interfaces as X-Window and MS-Windows) is an example for structured ordering of the interaction between man and computer.
Typical ordinary menu-based user interfaces in general only allow to `trigger' an event by selecting an appropriate menu entry. As a consequence of triggering an event often entry fields pop up on the screen where the user can enter numbers, select options and so on. This is possible because the character space of the screen is in general so large that the user has a consistent view of the human interface, even when there two, three or more input masks are popped up.
Problems arise, when the character space of the visual output device is rather small. Think of LC-displays of size 16x2, 16x4, 20x2 or 20x4 characters. Because the screen is so tiny, it is very important that a complex user interface is designed acccording to some fixed paradigm, so that the user is well-informed about every step in the interaction with the system. In character-limited devices interaction based on menus is even more important than on ordinary screens.
The principal idea presented in this document is to force the integration of the whole user interface into a menu structure. This means that not only the triggering of events is selected in the menu hierarchy, but also processing of possibly dozens of text-, input-, output- and notifier-fields. These elements are tightly integrated into the whole menu structure and thus make it superfluous, to have separate pop up fields for entering variables etc.
The sketch below shows a 16x4 LC-display, to give you an impression of the tinyness of the available character space.
________________ |................| |................| |................| |................| +----------------+ A 16x4 LC-display |
The M-Language is a notation for describing menu-directed user interfaces which are displayed on small LCD-panels (16x4 or 20x4). The menu-tree can be constructed by using many different elements, e.g. strings, integer i/o-fields, switches, options, soft functions keys and many more. Thus ML is especially well suited for embedded system design. A compiler for ML written in Python generates a block of tagged binary data which is self-containing and can easily be incorporated into ones own embedded application. In the sketch below mlc is applied to a menu specification `foo.m'. The binary menu image is generated into file `foo.c'. The interface declarations of the menu variables are contained within `foo.h'.
mlc foo.c menu specification ---------> (foo.m) foo.h |
On an embedded system connected to a LC-display, the binary menu data is `executed' with MEX, the "Menu Executor". MEX has no built in knowledge about a specific menu and is thus a generic piece of code which can easily be ported to other microcontrollers and embedded systems. MEX is fully written in the Ansi-C language, currently available for the 68HC11 and documented in See section `Introduction' in MEX --- The Menu Executor.
A typical case how to use M-language and MEX is depicted in the following sketch. Software for an embedded system consists in this picture of four primary object modules. A multitasker (MT), a system library (SYS) which contains low-level I/O functions, the application itself (APP) and the Menu Executor (MEX). MEX includes the binary menu image (`foo.c'). The application includes the header file generated by MLC (`foo.h'). The menu variables are either accessed directly from the application or via the generic entry-field functions contained in MEX. On leaving an entry-field a user installable callback-handler is called (see arrow `callback').
+----> APP <--- foo.h | MT callback SYS +----- MEX <--- foo.c, foo.h |
The M-Language was designed for describing menus to be displayed on small LCDs. To understand the concepts behind, one first has to define some notions, which are often used in this document. Some of the examples below depend on the actual display-algorithms for the menu which are implemented in MEX, so for details see the MEX documentation. See section `Introduction' in MEX -- The Menu Executor.
Temp..........
and second a two-digit input/output field,
shown by placeholder ##
.
|Temp..........##| |
A line can of course hold more than two line-components. The following example shows four components (string `'T1:'', integer field `##', string `' Time:'' and time-field `##.##').
|T1:## Time:##.##| |
|T_Beer........##| |T_Whiskey.....##| |T_Wodka.......##| |
>
character. Note that >
is not one of the
line-components but is placed there by the Menu EXecutor if it recognises
a sub-menu. If the submenu has an access password the character P
is shown instead of >
.
|T_Beer.........>| |T_Whiskey....## | |T_Wodka......## | |
The following lines show a possible sub-menu of menu-line
T_Beer
. It is displayed after pressing the key which is dedicated
for entering submenus.
|T_Budweiser...##| |T_Guinness....##| |T_Porter......##| |
The next chapter (see section 3. Elements of ML) first introduces some elementary concepts about ML. Thereafter the three different sections of a ML specification are introduced (menu-descriptor, menu-structs, menu-lines).
The structure of the Portable-Menu-Format (PMF) is featured in chapter (see section 4. The Portable-Menu-Format).
The last chapter contains an example ML specification which uses all of the concepts introduced in this document.
A menu specification in ML (Menu Language) is an ASCII text file with a simple list-based syntax. Currently the full description of a menu may be stored in one and only one file, because there exists no mechanism for including files into others. A ML-specification consists of three sections.
Section one, at the beginning of the specification, is the menu-descriptor, which holds some attributes concerning the appearance of the whole menu.
The next section comprises all menu-tables in the menu to be specified. The menu-tables fully describe the tree structure of the menu. They do not describe the individual outlook of each line. Section two is a sequence of all menu-tables in a tree.
Section three, the last section, is the description of the outlook of every single menu-line. Every menu-line in the whole menu must have a description of it's line-components in this third section.
Keywords of menu-specifications should be all written in lower-case.
3.1 Elementary ML 3.2 The Menu-Descriptor 3.3 The Menu-Table 3.4 The Menu-Line 3.5 The Menu-Line-Component (LC)
The universal building block of ML is a list. An example of a simple list is the following one:
(keyword ...) |
A list always begins with a (
character and ends with a )
character. The first word after the opening brace is a keyword, which
has to be selected according to the context. Note that keywords may contain
-
characters. The above example contains also some further
specification, which is denoted by ...
. This is also referred to as
the tail of the list. In the simplest form this is either a string,
an identifier, or a numerical value.
(value 'a string') # string (mnu-id menu0) # identifier (no quotes!) (delay 13) # numeric value |
In the above example we have three lists with the keywords value
,
menu-id
and delay
. The first line has some string data, the
second line an identifier data field and the third line has a numeric value.
Note also that #
is the comment leading character. All characters after
#
in the current line are ignored by the ML compiler.
The tail of a list is not restricted to those three simple formats but may contain also one or more other lists, as shown in the following example.
(format (key-1 ... ) (key-2 ... ) (key-3 ... ) ) |
Below is an example of the menu-descriptor
, which is the first main
component of a ML specification. According to the introducing words in
(see section 3.1 Elementary ML), it is a list containing some other lists.
(menu-descriptor ( menu-id m0) ( author 'H. Hoegl' ) ( date '3.1.1997' ) ( ml-version '0.1' ) ( delay-reset-all 120) ( delay-passwd 10) ( delay-help 2) ( org-var 0x8400 ) ) |
The following table is a short description of the different elementary
lists one must specify in the menu-descriptor
.
delay-reset-all
seconds, then the display
switches automatically to the toplevel menu-table.
delay-passwd
seconds, then
the password entry field will disappear.
delay-help
seconds a possibly displayed help text will
disappear.
This is the second part of a menu specification. It consists of one or more `menu-struct's' which define the hierarchy of the menu-lines. It is not a description of the actual line contents!
The following code example shows two menu-structs which define two menu-tables. On the first level, there are three lines m1, m2 and m3. Line m1 points to a submenu containing line m21.
The `menu-id' is needed to assign a menu-line with a short identifier which is also needed later when the actual contents of a line are described. Note that there are no qotes around the menu-id although it is not a keyword.
The `menu-parent' denotes the menu-id of the parent line. Note that the `menu-parent' of the topmost menu-table must have the value `nil'.
All lines in a menu-table must be listed with their menu-ids in the `menu-list' and attributed with either `leaf' or `submenu'.
The `menu-title' is an arbitary string which is compiled directly into the binary menu image. The menu executor can use this information freely. The current version of MEX writes this string left-adjusted to the first LCD line which is devoted entirely to status-information. It is recommended that this string reflects the current nesting level in a clear way: For example on should separate short level descriptors by a point as in `TOP.TEMP'.
(menu-struct ( menu-id m0 ) ( menu-parent nil ) ( menu-title 'TOP' ) ( menu-list (menu-id m1 submenu) (menu-id m2 leaf) (menu-id m3 leaf) ) ) (menu-struct ( menu-id m1 ) ( menu-parent m0 ) ( menu-title 'TOP.B' ) ( menu-list (menu-id m21 leaf) ) ) |
In principle each line can be attributed as a submenu and submenus may be nested to a reasonable level. The nesting level depends primarily on the chosen menu executor. The current implementation restricts this value due to low memory allocation to three.
The third section of a menu-description are one or more `menu-line' descriptors. In the previous section each menu-line got it's place in the menu hierarchie. Now each line is filled with it's actual line contents.
A menu-line is described by a list containing at least the two sublists
menu-id
and format
. The menu-id must be identical to one
of the menu-ids which have already been assigned in the `menu-struct'
section.
If a line points to a submenu, the process of entering this submenu can
be protected by a third sublist key
.
(menu-line (menu-id m1 ) (format ( <line-component> ... ) ( <line-component> ... ) ... ( <line-component> ... ) ) (key '0815') # optional access key for entering sub-menu ) |
A line-component is (nearly) the basic building block of a menu-line. Currently ML defines 10 different line-component types. Two of the line components have may appear in different formats: The `integer' field supports 10 different formats and the `float' field 2 different formats.
This section only defines the M-language syntax for line components. It does not tell anything about how the navigation and editing process is done (what keys have to be pressed etc.). Refer to the following document on how to edit writeable fields composed of these line components: See section `Introduction' in MEX - The Menu Executor.
A detailed description of how each line components is translated into header file declarations is given in the MLC documentation.
3.5.1 String 3.5.2 Integer 3.5.3 Float 3.5.4 Counter 3.5.5 Switchbox 3.5.6 Options 3.5.7 Time 3.5.8 The LC date 3.5.9 The LC hfill 3.5.10 The LC trigger
The `string' line component is the most basic one, because virtually in every menu-line a string is the first component. This string may specify the name of an input/output field, or be the name of a submenu and so on.
(string (blink off) (value 'T_Beer........') (access ro) (update 0) ) |
on
or off
. In the
on
case the string should blink with a fixed frequency. Note that
the attribute values are not strings. There must be no `'
surrounding the off
or on
values.
ro
(read only) or rw
(read/write).
In the first case (rp
) the string is fixed and can not be altered
by the user. The character sequence forming the string is simply stored in
the menu binary block.
In the second case (rw
), the string is alterable by the user.
Therefore it is necessary to copy the string from the menu binary block to
RAM. The rw
attribute for strings is currently not supported.
update
is only of any use when the access attribute
is rw
. It holds a numeric value specifying the period of
time in seconds between two updates of the string value. Maybe in a
multitasking environment one task alters the contents of the string, while
another task implements the Menu EXecutor. MEX knows when to update the
string by the attribute update
. Note that the update value 0
denotes an infinitely long period; this means the string is always
displayed without an udpate.
The integer field subsumes 10 different formatting styles. Depending on the style option it allows to display and, if writeable, also to edit either a two-byte or a one-byte integer. In many examples of embedded systems user-interfaces the range of these values is sufficient.
Future enhancements will bring also four-byte integers.
(integer (blink off) (type dd) # dd, sdd, ddd, sddd, SDDD, DDD, DDDD, DDDDD, # hh, HHHH (access rw) (update 10) (default 18) (var 'hztemp') ) |
dd
has a width of two characters. See the table below for a
list of all possible formatting options.
The float field subsumes 2 different formatting styles. Both have one digit behind the point and two or three integer digits. This is only a first attempt to integrate floats into the M-language. Probably other formats will also be necessary.
(float (blink off) (type sii.f) # sii.f, siii.f (access rw) (update 10) (default +2.4) (min -10.0) (max +10.0) (step 0.1) (var flt_var) ) |
The table below only shows the different formatting styles. For the other attributes see for example See section 3.5.2 Integer.
Note: Currently only the sii.f format is supported by MLC.
A `counter' is an integer input/output field, which allows only a fixed number
of numerical values. There is a start value from
, an end value
to
and the step size step
. All values can be displayed
which can be reached by subsequent addition or subtraction of `step'
from the default value.
(counter (blink off) (from 0) (to 10) (step 2) (default 8) (access rw) (update 0) (var 'hzcounter') ) |
If for example an input field needs to select among the values 0,2,4,6,8,10 then the best choice for the line-component type would be the `counter' (from = 0, to = 10, step = 2).
A hint for MEX implementations: The input field should not be changeable via the numerical keypad, but only via some cursor keys.
The switchbox is an input/output field that is similar to the switch-arrays used in Printed Connection Board design. An array of switches is shown as a string, where each character has either an `on' and `off' value. If the characters `*' and `.' mean on and off respectively, then the string
"*...*..*" |
defines a switch array, where the switches 1, 5 and 8 are in the `on'-state, and switches 2,3,4,6 and 7 are in the `off' state.
(switch (blink off) (nswitch 12) (swinfo 'Jan' 'Feb' 'Mar' 'Apr' 'Mai' 'Jun' 'Jul' 'Aug' 'Sept' 'Oct' 'Nov' 'Dec') (on-char '*') (off-char '.') (access rw) (default '***..**....*') (update 0) (var 'month_switch') ) |
The `option' line-component type is useful if an i/o-field may contain a value from a fixed list of alternatives. An easy example are the alternatives `on' and `off'.
(option (blink off) (nopts 2) (opts 'on' 'off') (default 0) (access rw) (update 0) (var 'my_opt') ) |
The following shows two examples how to specify a time value of type `long' and one of type `short'.
(time (blink off) (type long) (var 'time_x') (access rw) (update 1) (default '12:00.00') ) |
(time (blink off) (type short) (var 'time_y') (access rw) (update 60) (default '12:00') ) |
Note that the long format consists of three sub-components and the short format of two.
(date (blink off) (type long) (var 'date_x') (default '01/04/1997') (access rw) (update 0) ) |
(date (blink off) (type short) (var 'date_y') (default '01/04/97') (access rw) (update 0) ) |
The `hfill' line component insert whitespace characters between two other line-comps or between the beginning/ending of a line and a line-comp. It takes one argument which, if greater than zero, specifies the number of whitespace chars to be inserted.
If the argument is zero, than as many whitespaces are inserted so that the whole LCD line (e.g. 16 or 20 chars) is filled. This flexible whitespace field is useful for filling automatically the LCD width given in the display size (--lcd option of mlc.py). Note that currently only a single `(hfill 0)' is allowed within a menu line. With argument greater than zero there may be more than one `hfill's' within one line.
(hfill 2) # insert two whitespace chars (hfill 0) # flexible `glue' whitespace |
(trigger (blink off) (var 'TRIG_X') ) |
This entry field triggers some action. There are no other specifiers as the ones which are shown in the example. Character `X' is the symbol shown for the trigger or push-button. This line component is similar to pressing a push-button or a function key by calling the callback handler for this line-component.
The following sections contain the specification of PMF.
4.1 Notation 4.2 Overall Structure 4.3 LDTAGs (line descriptor tag, ldtag) 4.4 Line Options (line-opts) 4.5 LCTAGs (line component tag, lctag) 4.6 LCOs (Line Component Options, line-comp-opts)
Terminal symbols are enclosed in braces <..>
<foo:2>[2,0] | | | | | +- bits 2,1,0 | +------- size in bytes +---------- terminal symbol |
A sequence of bytes is stored big-endian. Example:
<foo:2>[2:0] is stored as x->|........|.....210| x points to foo |
Examples:
foo foo-bar |
{ foo } means zero or more repetitions |
menu ::= menu-table { menu-table } menu-table ::= <menu-entry-tag:2> menu-head menu-line { menu-line } menu-head ::= # Offset to first line-descriptor. The offset is at maximum 256. # Note that the header length does not include the menu-entry-tag. Add 2 # if this is what you want. <header-length:1> # Offset to next menu <next-menu-ofs:2> # Offset to prev menu <prev-menu-ofs:2> if <menu-entry-tag:2> == 0: # This is the toplevel menu # Version numbering 0.1 ... 256.256 <ml-version:2> # Automatically go to topmenu after n sec <delay-to-top:1> # Make help disappear after n sec <delay-clr-help:1> # Delay for password entry <delay-passwd:1> # Menu name (will be display on the top left corner of the LCD) <menu-name-str:n> menu-line ::= <ldtag:1> line-opts line-comp { line-comp } line-comp ::= <lctag:1> line-comp-opts |
The `<menu-entry-tag:2>[3:0]' contains the menu level, e.g. 0 for the top menu entry, 1 for the first level submenu entry, 2 for the second level submenu entry and so on.
The elements `ldtag', `line-opts', `lctag' and `line-comp-opts' are described in the following sections.
<ldtag:1>[1,0] 00 : >= 3 lines, not first nor last 01 : first menu line 10 : last menu line 11 : first is equal last line <ldtag:1>[3,2] 00 : no submenu, no parent 01 : is submenu, no parent 10 : has parent, no submenu 11 : is submenu and has parent <ldtag:1>[4] 0 : if submenu, no passwd needed 1 : if submenu, passwd needed |
if (<ldtag>[3,0] == 00xx) line-opts ::= <next-ofs:2> <prev-ofs:2> |
if (<ldtag>[3,0] == 01xx) line-opts ::= <next-ofs:2> <prev_ofs:2> <dn-menu-OFS:2> |
if (<ldtag>[3,0] == 11x1) line-opts ::= <next-ofs:2> <up-menu-ofs:2> <dn-menu-OFS:2> |
if (<ldtag>[3,0] == 11x0) line-opts ::= <next-ofs:2> <prev-ofs:2> <dn-menu-OFS:2> |
if (<ldtag>[3,0] == 10x1) line-opts ::= <next-ofs:2> <up-menu-OFS:2> |
if (<ldtag>[3,0] == 10x0) line-opts ::= <next-ofs:2> <prev-ofs:2> |
if (<ldtag>[4] == 1) line-opts ::= ... <passwd-string:n> |
The password is appended to the previous options.
<lctag:1>[4,0] data type mask range comment ----------------------------------------------------------------------- 0x00 uchar dd 0..99 D = Digit 0x01 uchar ddd 0..255 0x02 char sdd -99..+99 S = Sign 0x03 char sddd -128..+127 0x04 uint:2 DDD 0..999 0x05 int:2 SDDD -999..+999 0x06 uint:2 DDDD 0..9999 0x07 uint:2 DDDDD 0..2^16-1 0x08 uchar HH 0..FF Hex 0x09 uint:2 HHHH 0..FFFF Hex 0x0a string "..." "..." 0x0b <not used> 0x0c counter DD..D from/to/step 0x0d switch .*..**. - max 32 sw 0x0e option "..." opt1, opt2, ... 0x0f time-long 12:44:13 - 0x10 time-short 12:44 - 0x11 float SII.F -99.9..+99.9 0x12 float SIII.F -999.9..+999.9 0x13 passwd "..." - 0x14 date-long 01/01/1997 - 0x15 date-short 01/01/97 - 0x16 trigger 1 char - 0x17-0x1f not used |
<lctag:1>[7] 0 : not last component of current line 1 : last component of current line |
<lctag:1>[6] 0 : not blink 1 : blink |
<lctag:1>[5] 0 : access is read only (better: display only) 1 : access is read/write: modifyable via keyboard |
Notes:
LCL = variable (explicitly given in the LCO)
if (<lctag:1>[4,0] == 0x0a) if (<lctag:1>[5] == 0) # constant string (access=RO) <string:n+1> # n=0..255 else # variable string (access=RW) <update:1> <string:n+1> <addr:2> <call_addr:2> |
LCL = 6 (implicitly given in the LCO)
if (<lctag:1>[4,0] == 0x00) <update:1> <def:1> <addr:2> <call_addr:2> |
LCL = 6
if (<lctag:1>[4,0] == 0x01) <update:1> <def:1> <addr:2> <call_addr:2> |
LCL = 6
if (<lctag:1>[4,0] == 0x02) <update:1> <def:1> <addr:2> <call_addr:2> |
LCL = 6
if (<lctag:1>[4,0] == 0x03) <update:1> <def:1> <addr:2> <call_addr:2> |
LCL = 7
if (<lctag:1>[4,0] == 0x04) <update:1> <def:2> <addr:2> <call_addr:2> |
LCL = 7
if (<lctag:1>[4,0] == 0x05) <update:1> <def:2> <addr:2> <call_addr:2> |
LCL = 7
if (<lctag:1>[4,0] == 0x06) <update:1> <def:2> <addr:2> <call_addr:2> |
LCL = 7
if (<lctag:1>[4,0] == 0x07) <update:1> <def:2> <addr:2> <call_addr:2> |
LCL = 6
if (<lctag:1>[4,0] == 0x08) <update:1> <def:1> <addr:2> <call_addr:2> |
LCL = 7
if (<lctag:1>[4,0] == 0x09) <update:1> <def:2> <addr:2> <call_addr:2> |
LCL = 14
Note: `from' and `to' are interpreted as signed numbers!
if (<lctag:1>[4,0] == 0x0c) <upd:1> <field-width:1> <from:2> <to:2> <step:2> <def:2> <addr:2> <call_addr:2> # always present |
LCL = variable
if (<lctag:1>[4,0] == 0x0d) <length:1> <upd:1> <nswitch:1> # 1...32 switches (4 byte) <on-char:1> <off-char:1> <def:4> # default mask <addr:2> # address of mask <call_addr:2> # address of RW handler <string:n+1> # help string ... <string:n+1> # help string |
LCL = variable
if (<lctag:1>[4,0] == 0x0e) <length:1> <upd:1> <nopts:1> <width:1> <def:1> <addr:2> <call_addr:2> <string:n+1> # list of option strings ... <string:n+1> |
The current option index is stored in an unsigned char, to which `addr' points. Thus there is a maximum of 256 different options.
LCL = 8
if (<lctag:1>[4,0] == 0x0f) <upd:1> <addr:2> <call_addr:2> <def:3> |
LCL = 7
if (<lctag:1>[4,0] == 0x10) <upd:1> <addr:2> <call_addr:2> <def:2> |
[changed 2004-05-24]
LCL = 21
if (<lctag:1>[4,0] == 0x11) <update:1> <default:4> <min:4> ; float <max:4> ; float <step:4> ; float <addr:2> <call_addr:2> |
LCL = 9
if (<lctag:1>[4,0] == 0x12) <update:1> <default:4> <addr:2> <call_addr:2> |
LCL = variable
if (<lctag:1>[4,0] == 0x13) <length:1> <passwd-string:n+1> <call_addr:2> |
Note: Don't mix the password line component with the submenu access key. They have different meanings. The submenu access key is part of the line options following the line descriptor tag.
LCL = 9
if (<lctag:1>[4,0] == 0x14) <update:1> <addr:2> <call_addr:2> <def:4> |
LCL = 8
if (<lctag:1>[4,0] == 0x15) <update:1> <addr:2> <call_addr:2> <def:3> |
LCL = 2
if (<lctag:1>[4,0] == 0x16) <call_addr:2> |
# -- menu1.m -- # H. Hoegl, 3.1.1997 # Menu description example using ML (Menu Language) # tests following component types: # integer, string, counter, time, date # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # menu structure # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (menu-descriptor ( menu-id m0) ( author 'H. Hoegl' ) ( date '3.1.1997' ) ( ml-version '0.1' ) # Some constants for managing the display (timescale seconds). # two minutes and we'll be back at root menu. ( delay-reset-all 120) # show as long the passwd entry field after a try to step into a # subdir. Value 0 means 'show always'. ( delay-passwd 10) # a help text is displayed for this period of time. Value 0 means # 'show until help key was pressed a 2nd time'. Maybe scrolling should # be allowed. Then help text disappears this time delay after last # scrolling action. ( delay-help 2) # Start address for menu variables. All vars are stored sequentially # beginning at the start address. ( org-var 0x7000 ) ) (menu-struct ( menu-id m0 ) ( menu-parent nil ) ( menu-title 'MOPS-O-MAT' ) ( menu-list (menu-id m1 submenu) (menu-id m2 leaf) (menu-id m3 submenu) (menu-id m4 leaf) (menu-id m5 leaf) (menu-id m6 leaf) ) ) (menu-struct ( menu-id m1 ) ( menu-parent m0 ) ( menu-title 'TOP.B' ) ( menu-list (menu-id m21 leaf) ) ) (menu-struct ( menu-id m3 ) ( menu-parent m0 ) ( menu-title 'TOP.C' ) ( menu-list (menu-id m31 leaf) (menu-id m32 leaf) (menu-id m33 leaf) (menu-id m34 submenu) ) ) (menu-struct ( menu-id m34 ) ( menu-parent m3 ) ( menu-title 'TOP.C.A' ) ( menu-list (menu-id m40 leaf) ) ) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # modelling menu lines # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (menu-line (menu-id m1 ) (format (string (blink off) (value 't_h2o.... ') (access ro) (update 0) ) (counter (blink off) (from 0) (to 12) (step 2) (default 4) (access rw) (update 3) (var 'hztemp1') ) ) ) (menu-line (menu-id m2 ) (format (string (blink off) (value 'int: ') (access ro) (update 0) ) (integer (blink off) (type dd) (access ro) (update 10) (default 18) (var 'hztemp') ) ) ) (menu-line (menu-id m3 ) (format (string (blink off) (value 'line 3... ') (access ro) (update 0) ) (counter (blink off) (from -10) (to 10) (step 2) (default 8) (access rw) (update 0) (var 'hzcounter_0') ) ) ) (menu-line (menu-id m4 ) (format (string (blink off) (value 'c1:') (access ro) (update 0) ) (counter (blink off) (from -10) (to 2000) (step 1) (default 19) (access rw) (update 0) (var 'hzcounter_1') ) (string (blink off) (value ' c2:') (access ro) (update 0) ) (counter (blink off) (from 40) (to 80) (step 5) (default 40) (access rw) (update 0) (var 'hzcounter_2') ) ) ) (menu-line (menu-id m5 ) (format (string (blink off) (value 'Time: ') (access ro) (update 0) ) (time (blink off) (type short) (access rw) (update 3) (default '20:15') (var 'timer_b') ) ) ) (menu-line (menu-id m6 ) (format (string (blink off) (value '1: ') (access ro) (update 0) ) (date (blink off) (type short) (access rw) (update 3) (default '12/04/61') (var 'date_a') ) ) ) (menu-line (menu-id m21 ) (format (string (blink off) (value 'abc...') (access ro) (update 0) ) ) ) (menu-line (menu-id m31 ) (format (string (blink off) (value 'fubar') (access ro) (update 0) ) ) ) (menu-line (menu-id m32 ) (format (string (blink off) (value 'foo') (access ro) (update 0) ) ) ) (menu-line (menu-id m33 ) (format (string (blink off) (value 'string 5') (access ro) (update 0) ) ) ) (menu-line (menu-id m34 ) (format (string (blink off) (value 'string 4') (access ro) (update 0) ) ) ) (menu-line (menu-id m40 ) (format (string (blink off) (value 'core dumped...') (access ro) (update 0) ) ) ) |
[Top] | [Contents] | [Index] | [ ? ] |
[Top] | [Contents] | [Index] | [ ? ] |
1. Document History
2. Introduction
3. Elements of ML
4. The Portable-Menu-Format
5. An example menu specification
[Top] | [Contents] | [Index] | [ ? ] |
Button | Name | Go to | From 1.2.3 go to |
---|---|---|---|
[ < ] | Back | previous section in reading order | 1.2.2 |
[ > ] | Forward | next section in reading order | 1.2.4 |
[ << ] | FastBack | previous or up-and-previous section | 1.1 |
[ Up ] | Up | up section | 1.2 |
[ >> ] | FastForward | next or up-and-next section | 1.3 |
[Top] | Top | cover (top) of document | |
[Contents] | Contents | table of contents | |
[Index] | Index | concept index | |
[ ? ] | About | this page |