Customizing menu items part 1

Over the past years, I have not posted articles dealing with menu items. I have shown how to directly access menu items’ hidden handles, but not much more than that. A year ago I promised a mini-series on menu customizations, and it’s time to keep my promise. In today’s article, the first in the mini-series, I will present several undocumented menu customization topics that rely on pure-Matlab (i.e, no Java today). The next article in this series will focus on Java-based customizations.

Invoking menu item callbacks

As noted above, a figure window’s menu items can be directly accessed. Once we access a menu item’s handle, we can extract its Callback property and directly invoke it (for example, using the semi-documented hgfeval function). Note that menu callbacks are kept in Callback, while toolbar callbacks are kept in ClickedCallback.

Menu callbacks generally use internal semi-documented functions (i.e., having a readable help section but no doc, online help, or official support), which are part of Matlab’s uitools folder. These functions are specific to each top-level menu tree: filemenufcn, editmenufcn, viewmenufcn, insertmenufcn, toolsmenufcn, desktopmenufcn, winmenu, and helpmenufcn implement the figure’s eight respective top-level menu trees’ callbacks. These functions accept an optional figure handle (otherwise, gcbf is assumed), followed by a string specifying the specific menu item whose action needs to be run. webmenufcn implements the Help menu’s Web Resources sub-menu callbacks in a similar manner.

Use of these functions makes it easy to invoke a menu action directly from our Matlab code: instead of accessing the relevant menu item and invoking its Callback, we simply find out the menu item string in advance and use it directly. For example,

filemenufcn FileClose;
editmenufcn(hFig,'EditPaste');

uimenufcn is a related fully-undocumented (built-in) function, available since Matlab R11 (late 1990s). It accepts a figure handle (or the zero [0] handle to indicate the desktop) and action name. For example, the fully-documented commandwindow function uses the following code to bring the Command Window into focus:

uimenufcn(0, 'WindowCommandWindow');

Customizing menus via uitools

makemenu is another semi-documented uitool function that enables easy creation of hierarchical menu trees with separators and accelerators. It is a simple and effective wrapper for uimenu. makemenu is a useful function that has been made obsolete (grandfathered) without any known replacement.

makemenu accepts four parameters: a figure handle, a char matrix of labels (‘>’ indicating sub item, ‘>>’ indicating sub-sub items etc.; ‘&’ indicating keyboard shortcut; ‘^x’ indicating an accelerator key; ‘-‘ indicating a separator line), a char matrix of callbacks, and an optional char matrix of tags (empty by default). makemenu makes use of another semi-documented grandfathered function, menulabel, to parse the specified label components. makemenu returns an array of handles of the created uimenu items:

labels = str2mat('&File', ...    % File top menu
           '>&New^n', ...           % File=>New
           '>&Open', ...            % File=>Open
           '>>Open &document^d', ...    % File=>Open=>doc
           '>>Open &graph^g', ...       % File=>Open=>graph
           '>-------', ...          % File=>separator line
           '>&Save^s', ...          % File=>Save
           '&Edit', ...		% Edit top menu
           '&View', ...		% View top menu
           '>&Axis^a', ...          % View=>Axis
           '>&Selection region^r'); % View=>Selection
calls = str2mat('', ...		% no action: File top menu
           'disp(''New'')', ...
           '', ...			% no action: Open sub-menu
           'disp(''Open doc'')', ...
           'disp(''Open graph'')', ...
           '', ...			% no action: Separator
           'disp(''Save'')', ...
           '', ...			% no action: Edit top menu
           '', ...			% no action: View top menu
           'disp(''View axis'')', ...
           'disp(''View selection region'')');
handles = makemenu(hFig, labels, calls);
set(hFig,'menuBar','none');

A simple figure menu

A simple figure menu

Customizing menus via HTML

Since menu items share the same HTML/CSS support feature as all Java Swing labels, we can specify font size/face/color, bold, italic, underline, superscript/subscript, and practically any HTML formatting.

Note that some features, such as the font or foreground/background colors, have specific properties that we can set using the Java handle, instead of using HTML. The benefit of using HTML is that it enables setting all the formatting in a single property. HTML does not require using Java – just pure Matlab (see the following example).

Multi-line menu items can easily be done with HTML: simply include a <br> element in the label – the menu item will split into two lines and automatically resize vertically when displayed:

txt1 = '<html><b><u><i>Save</i></u>';
txt2 = '<font color="red"><sup>this file</sup></font></b></html>';
txt3 = '<br />this file as...';
set(findall(hFig,'tag','figMenuFileSave'),   'Label',[txt1,txt2]);
set(findall(hFig,'tag','figMenuFileSaveAs'), 'Label',[txt1,txt3]);

A multi-line HTML-rendered menu item

A multi-line HTML-rendered menu item

set(hMenuItem, 'Label',['<html>&2: C:\My Documents\doc.txt<br />'
   '<font size="-1" face="Courier New" color="red">&nbsp;&nbsp; '
   'Date: 15-Jun-2011 13:23:45<br />&nbsp;&nbsp; Size: 123 KB</font></html>']);

HTML-rendered menu items

HTML-rendered menu items

Much more complex customizations can be achieved using Java. So stay tuned to part 2 of this mini-series…

Note: Menu customization is explored in depth in section 4.6 of my book.

Categories: Figure window, GUI, Low risk of breaking in future versions, Semi-documented function

Tags: , , , , ,

Bookmark and SharePrint Print

6 Responses to Customizing menu items part 1

  1. quant says:

    HI Yair,
    not related to this post, but was curious if you
    Have you ever worked on the solution to this :

    http://stackoverflow.com/questions/5554518/can-matlab-not-read-back-a-double-array-from-java

    • Malcolm Lidierth says:

      It is not a bug, it is expected behaviour

      firstfunction accepts a copy of a MATLAB double array, modifies that copy and returns without altering anything in the MyClass instance.

      secondfunction gets a reference to a java.lang.Double array as input- so MATLAB sees the changes made to that object

    • @Malcolm, I believe the OP does not dispute the fact that this is the expected behavior, he/she was simply asking whether there is any way to circumvent or modify this behavior. I do not know of any, but this is not saying that there isn’t any…

  2. Pingback: Customizing menu items part 2 | Undocumented Matlab

  3. Pingback: Customizing the standard figure toolbar, menubar | Undocumented Matlab

Leave a Reply


Your email address will not be published. Required fields are marked *