wiki:plugin_menu

This Plugin is not part of the current lcd4linux. This wiki entry was created for discussion about a plugin prototype.

Plugin Menu


/raw-attachment/wiki/FutabaVFD/FutabaVFD_Menu_Serial.png
Plugin Menu, ctrl_serial (2 LED, 4 Buttons), Futaba VFD

1. Description

The plugin Menu allows to configure and use menus.

This Plugin uses plugin Layout to switch Layouts. Therefore plugin Layout has to be configured and activated too.
Due to this and the similar use of actions it's highly recommended to read the wiki entry of plugin Layout first.

While simple menus can be create with plugin Layout by using the change of button functions depending on the current layout, with plugin Menu menus are builded by using item selection and button functions that are depending on the current active item. So more choises can be made on a small display or with very few buttons. Its also a more natural way to build menus if controls with arrow buttons (e.g. widget Keypad) are used.

A part of a menu configured in the attached sample config file looks like this:

┌────────────────────────────────────────┐
│1.1/1.2     Main Menu 1/2               │
│ [SET VALUE] >CPU< [RAM] [DISK] [ETH] >>│
└────────────────────────────────────────┘

In this example CPU is setected, inactive items are marked with [...] to distinguish between selectable items and normal text like the title (Main Menu...).

The plugin Menu does NOT draw any item or menu itself. It only stores the current menu and item internally and provides functions to switch the current menu or item and functions to detect if a menu/item is active. Latter functions are used by visible widgets (usually the Text widget) to make the menu state visible (e.g. marks or blink). The functionality of the menus is specified by setting actions for each item. By this its very adjustable how a menu look and acts but that is paid with a more complex configuration.



2. Configuration

2.1. Structure

The structure in the config-file looks like this:

    Plugin Menu {

        active 1

        blink 150
        initmenu 'M_Menu'

        confirm layout::confirm()
        cancel  layout::cancel()
        left    layout::left()
        right   layout::right()

        Menu1 {
            name 'M_Menu'
            
            layoutgroup 'G_Menu'

       	    confirm menu::none(); layout::layout('G_Diff','L_Dummy')
            cancel  ' '
            left    menu::prev(0)
            right   menu::next(0)

            Item1 {
                name    'I_Menu_SET'
                layout  'L_Menu_1'
       	        confirm menu::menu('M_SET')
            }

            Item2 {
                name    'I_Menu_CPU'
                confirm menu::none(); layout::layout('G_Diff','L_CPU')
            }

            ...
        }
        
        Menu2 {
            ...
        }
    }
    ...

    Widget W_Menu_CPU {
        class 'text'
        update t_item
        width 5  
        expression menu::if('M_Menu','I_Menu_CPU','>CPU<','[CPU]')                      
    }
    ...

"active 1" activates the plugin. If it has not been activated all of its functions will return -1.

The plugin must contain at least 1 menu - each menu at least 1 item. Menus and items have to be numbered serially starting with 1.

In the example a text widget linked to item I_Menu_CPU of menu M_Menu is shown. If this item is active, the widget will be drawn as >CPU<, else [CPU] Of course menu::if() could be used in the prefix and postfix expressions of the text widget too.

Widgets which are linked to a menu item that way have to poll the current menu state periodically. Using a variable to set the update parameter of the widget to a decisecond might be a good idea.

For each menu a layout group has to be set. For each menu the layout of the first item has to be set explicitly. For all other items it's assumed that it has the same layout as its previous item if no layout was set. Of course this layout should contain the widget which represents the item visually.

If the current menu/item is switched the plugin will switch to the layout which was set for this item automatically.

2.2. Section Plugin Menu

Parameters:

activeSet to 1 to activate plugin, otherwise the plugin won't work and all of its functions return -1.
initmenu*Name of the menu that should be active initially (first item). (If not set: No menu/item is active at the start.)
blink*Duration in milliseconds between a state change in function menu::blink(...); default: 200
<actions>*see Actions
* optional

Subsections

Menussee Subsection Menu

2.3. Subsection Menu

Parameters:

name*Unique name of the menu. Default: 'Menu1' for Menu1, ...
layoutgroupLayout group of the menu.
<actions>*see Actions
* optional

Subsections

Itemssee Subsection Item

2.4. Subsection Item

Parameters:

nameName of the item. Default: 'Item1' for Item1, ...
layoutLayout of the item.
<actions>*see Actions
* optional, sometimes optional

2.5. Actions

Actions are parameters whose values are expressions which will be evaluated when the action is triggered.

These actions can be used to modify the function of button/timer events dependent on the current item/menu.

onenter*Triggered shortly after enter new item/menu.
onexit*Triggered shortly before exit new item/menu.
confirmTriggered by menu::confirm()
cancelTriggered by menu::cancel()
upTriggered by menu::up()
downTriggered by menu::down()
leftTriggered by menu::left()
rightTriggered by menu::right()
action1Triggered by menu::trigger('action1')
...
action 20Triggered by menu::trigger('action20')
* only in subsection Menu and Item

The actions "onenter" and "onexit" will be triggered by a change of the current active item. This may result in switching the current layout. In this case onexit/onenter of plugin Layout will be evaluated too.

Sequence:

  1. onexit of old item
  2. onexit of old menu
  3. switch menu/item
  4. onexit of old layout
  5. onexit of old group
  6. switch group/layout
  7. onenter of new group
  8. onenter of new layout
  9. onenter of new menu
  10. onenter of new item

The other actions will be triggered directly by homonymic functions in the following way.

item level ==> menu level ==> plugin level (First matching action found will be triggered.)

For instance the confirm actions in the example above:

Usually the confirm action is defined for each item to switch to a new layout or another menu, if it's triggered by menu::confirm(). Since some items in the samples are dummies these items will have no confirm action, because it can be set as default for Menu1 (M_Menu). After this confirm action is evaluated no menu will be set because of menu::none(). Now a call of menu::confirm() is handled on plugin level and gets redirected to a call of layout::confirm(). This redirection on plugin level is useful because menus will often lead to layouts without a active menu but the need to react on buttons - especially cancel to get back to the menu.

3. Functions


All functions return -1 on error (e.g. plugin not active, wrong config, wrong indexes, name not found).

FunctionArgsDescription
Item info/switch
menu::item( [[menu],item] ) 0-2 switches to item or get current item index of the current menu. See below.
menu::items() 0 returns number of items in current menu
menu::itemname() 0 returns name of the current item
menu::prev( loop ) 1 switch to previous item of current menu - no change if first item of menu and loop == 0, returns -1 on error, else 0
menu::next( loop ) 1 switch to next item of current menu - no change if last item of menu and loop == 0, returns -1 on error, else 0
Menu info/switch
menu::menu( [menu] ) 0-1 returns menu index or switches to last active item of menu. See below.
menu::menus() 0 returns number of menus
menu::menuname() 0 returns name of current menu
menu::none() 0 No menu is active after this function was called.
Functions to use in widget expressions
menu::if( menu, item, ifVal, elseVal ) 4 returns ifVal if item of menu is active, else elseVal. menu & item may be the names or the indexes.
menu::blink( menu, item, val, [elseVal] ) 3-4 Return 'blinking text'. menu & item may be the names or the indexes. See below.
menu::check( menu, item ) 2 returns 1 if item of menu is active, else 0. menu & item may be the names or the indexes.
Action trigger
menu::trigger( arg ) 1 See Actions, Examples for value of arg: 'action17', 'confirm' , returns 1 if action found, else 0
menu::confirm() 0 See Actions, returns 1 if action found, else 0
menu::cancel() 0 See Actions, returns 1 if action found, else 0
menu::left() 0 See Actions, returns 1 if action found, else 0
menu::right() 0 See Actions, returns 1 if action found, else 0
menu::up() 0 See Actions, returns 1 if action found, else 0
menu::down() 0 See Actions, returns 1 if action found, else 0


menu::item( [[menu],item] )

menu::item()returns index of current item within current menu or 0 if no menu is active
menu::item(item)switch to item within current menu, item may be the name or the index of the item, returns -1 on error, else 0
menu::item(menu,item)switch to item of menu, menu & item may be the names or the indexes, returns -1 on error, else 0


menu::menu( [menu] )

menu::menu()returns index of current menu or 0 if no menu is active
menu::menu(menu)switch to the last active item (default: first) of menu. menu may be the name or the index of the menu, returns -1 on error, else 0


menu::blink( menu, item, val, [elseVal] )
If item of menu is active, val or a blank string of the same length are returned. This value alternates blink milliseconds what results in blinking.

If item of menu is not active, elseVal will be return if set, a non blinking val otherwise.

Note: Since the update frequency of the widget which calls menu::blink(...) an the frequency of the blinking effect will interfere, it is highly recommended to set each of the update parameter of these widget to be a proper divisor of the value of blink.

4. Example

Download: sample_menu.conf

The example is written for the Curses driver. So no real LCD is needed for testing. It also allows the use of the keyboard to switch layouts. (If the real display has no keypad the Control plugin may be used to connect buttons to lcd4linux.)

Use option -f to activate these configuration files.

The indexes of the group, layout, menu and item are displayed in the upper left corner of all layouts to make it easy to find the matching part in the config file.

Control

The example can be controlled with the 4 arrow keys of the keyboard using the keypad. This is already configured in the sample.

Beside that other controllers could be used to. A sample configuration of plugin Control is included but the plugin is set to inactive, since there would be parameters to set and controllers to install before the plugin would work.

(Note: The Curses driver will react on mouse wheel movements since the mouse has not been detached from the kernel by the usb mouse controller.)

KeypadFunctionctrl_fifo*ctrl_usbmouse*ctrl_serial*
upconfirm / enter or leave edit modesend "o" (ok) to fifoleft mouse buttonbutton S2
downback to main menusend "c" to fiforight mouse buttonbutton S2
leftprevious item / valuesend "l" to fifoscroll upbutton S1
rightnext item / valuesend "r" to fifoscroll downbutton S0
*by plugin Control

Main menu

The example will start on the first of two sites of the main menu. Except the first 2 items all other items are dummies du demonstrate item switching. On the first site of the main menu uses uniform style for marking the active item. On the second site some other possibilies (e.g. blinking) are shown.

Items are switched by the arrow keys left and right. All of this items act as buttons. To confirm (press one of these virtual buttons) arrow key up is used. Pressing arrow key down (cancel) will have no effect in the main menu. Outside the main menu cancel will return to it.

Set value

This is the first item of the main menu. It leads to a new layout and menu. This menu contains two items. These items act as combo boxes. In normal mode items are switched by the arrow keys left and right. By pressing arrow key up the current item is set to edit mode. Now the value of the combo box (indeed the value of a variable modified by actions) can be switched by the arrow keys left and right. The edit mode can be left by pressing arrow key up again.

(Note: The List plugin is used to hold/select the switchable values.)

CPU

This is the second item of the main menu. It leads to a dummy with some bars. Pressing arrow key down (cancel) will return to the main menu.

Generic dummy

All except the first two items of the main menu will lead to this view with a scrolling text. Pressing arrow key down (cancel) will return to the main menu.

Last modified 4 years ago Last modified on 11/01/15 18:31:57

Attachments (1)

Download all attachments as: .zip