uisplittool & uitogglesplittool

Matlab 7.6 (R2008a) and onward contain a reference to uisplittool and uitogglesplittool in the javacomponent.m and %matlabroot%/bin/registry/hg.xml files. These are reported as built-in functions by the which function, although they have no corresponding m-file as other similar built-in functions (note the double ‘t’, as in split-tool):

>> which uisplittool
built-in (C:\Matlab\R2010b\toolbox\matlab\uitools\uisplittool)

These uitools are entirely undocumented, even today (R2010b). They puzzled me for a very long time. An acute reader (Jeremy Raymonds) suggested they are related to toolbars, like other uitools such as the uipushtool and uitoggletool. This turned out to be the missing clue that unveiled these useful tools:

So what are uisplittool and uitogglesplittool?

Both uisplittool and uitogglesplittool are basic Handle-Graphics building blocks used in Matlab toolbars, similarly to the well-documented uipushtool and uitoggletool.

uisplittool presents a simple drop-down, whereas uitogglesplittool presents a drop-down that is also selectable.

The Publish and Run controls on the Matlab Editor’s toolbar are examples of uisplittool, and so are the Brush / Select-Data control on the figure toolbar, and the plot-selection drop-down on the Matlab Desktop’s Workspace toolbar:

uisplittool in action in the Matlab Desktop

uisplittool in action in the Matlab Desktop

Adding uisplittool and uitogglesplittool to a toolbar

Adding a uisplittool and uitogglesplittool to a toolbar is done in a similar manner to adding uipushtools and uitoggletools:

hToolbar = findall(gcf,'tag','FigureToolBar');
hUndo=uisplittool('parent',hToolbar);       % uisplittool
hRedo=uitogglesplittool('parent',hToolbar); % uitogglesplittool

Like uipushtool and uitoggletool, uisplittool and uitogglesplittool also have unique Type property values, ‘uisplittool’ and ‘uitogglesplittool’ respectively. The handles can also be tested using the built-in isa function:

>> isa(handle(hUndo),'uisplittool')   % or: 'uitogglesplittool'
ans =
     1
>> class(handle(hUndo))
ans =
uisplittool

Just as with uipushtools and uitoggletools, the new buttons have an empty button-face appearance, until we fix their CData, Tooltip and similar settable properties:

% Load the Redo icon
icon = fullfile(matlabroot,'/toolbox/matlab/icons/greenarrowicon.gif');
[cdata,map] = imread(icon);
 
% Convert white pixels into a transparent background
map(find(map(:,1)+map(:,2)+map(:,3)==3)) = NaN;
 
% Convert into 3D RGB-space
cdataRedo = ind2rgb(cdata,map);
cdataUndo = cdataRedo(:,[16:-1:1],:);
 
% Add the icon (and its mirror image = undo) to latest toolbar
set(hUndo, 'cdata',cdataUndo, 'tooltip','undo','Separator','on', ...
           'ClickedCallback','uiundo(gcbf,''execUndo'')');
set(hRedo, 'cdata',cdataRedo, 'tooltip','redo', ...
           'ClickedCallback','uiundo(gcbf,''execRedo'')');

User-created uisplittool & uitogglesplittool toolbar buttons

User-created uisplittool & uitogglesplittool toolbar buttons

Note that the controls can be created with these properties in a single command:

hUndo = uisplittool('parent',hToolbar, 'cdata',cdataRedo, ...);

Re-arranging the toolbar controls placement

Let us now re-arrange our toolbar buttons. Unfortunately, a bug causes uisplittools and uitogglesplittools to always be placed flush-left when the toolbar’s children are re-arranged (anyone at TMW reading this in time for the R2011a bug-parade selection?).

So, we can’t re-arrange the buttons at the HG-children level. Luckily, we can re-arrange directly at the Java level (note that until now, the entire discussion of uisplittool and uitogglesplittool was purely Matlab-based):

jToolbar = get(get(hToolbar,'JavaContainer'),'ComponentPeer');
jButtons = jToolbar.getComponents;
for buttonId = length(jButtons)-3 : -1 : 7  % end-to-front
   jToolbar.setComponentZOrder(jButtons(buttonId), buttonId+1);
end
jToolbar.setComponentZOrder(jButtons(end-2), 5);   % Separator
jToolbar.setComponentZOrder(jButtons(end-1), 6);   % Undo
jToolbar.setComponentZOrder(jButtons(end), 7);     % Redo
jToolbar.revalidate;

Re-arranged uisplittool & uitogglesplittool toolbar buttons

Re-arranged uisplittool & uitogglesplittool toolbar buttons
(not as simple as it may sound)

Next week, I will combine the information in this article, with last year’s articles about uiundo, and show how we can create a dynamic figure toolbar drop-down of undo/redo events. Here is a preview to whet your appetite:

undo/redo buttons implemented using uisplittool

undo/redo buttons implemented using uisplittool

Categories: Desktop, Figure window, Medium risk of breaking in future versions, Stock Matlab function, UI controls, Undocumented function

Tags: , , , , ,

Bookmark and SharePrint Print

9 Responses to uisplittool & uitogglesplittool

  1. Yogesh says:

    Thanks. I find this useful.

  2. Dan says:

    out of topic, but thank you for your efforts.

    You are of great help to many Matlab practitioners!

    Best regards

    Dan

  3. cK says:

    I was curious to know if there is a way to retain transparency of png images or even convert white pixels of a logo image into transparent background (it looks sweet on GUIs). I tried the following on a gif image and the image still gave a white background. Why doesnt it work?

    [cdata,map] = imread('logo.gif');
    map(find(map(:,1)+map(:,2)+map(:,3)==3)) = NaN;
    % Convert into 3D RGB-space
    cdata2 = ind2rgb(cdata,map);
    image(cdata2);
    • @cK – Transparency only works in GUI controls. It is unfortunately not supported by Matlab’s image function that displays the image in Matlab plot axes.

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

  5. Christina says:

    I’m using this capability with 2013a but am having a problem with it crashing. I tried putting my code in the GUIDE OpeningFcn as well as the OutputFcn but get the same results. My code is as follows:

    color = java.awt.Color(0,0,0);
     
    % hToolbar = findall(gcf,'tag','hToolbar');
    jToolbar = get(get(handles.hToolbar,'JavaContainer'),'ComponentPeer');
     
    % Create a splittool for different options
    hLayout = uisplittool('parent',handles.hToolbar);       % uisplittool
     
    % Load the icon
    icon = fullfile(pwd,'icons','Icon.gif');
    [cdata,map] = imread(icon);
    map(find(map(:,1)+map(:,2)+map(:,3)==3)) = NaN;
     
    set(hLayout, 'tag','testingButton','cdata',ind2rgb(cdata,map), 'tooltip','Layout Types','Separator','on', ...
               'ClickedCallback',[]);
     
    jLayout = get(hLayout,'JavaContainer');
    jLayoutMenu = jLayout.getMenuComponent;
    imageToolkit = java.awt.Toolkit.getDefaultToolkit;
    for layoutInd = 1:3
        jMenuItem = handle(jLayoutMenu.add(['Layout ' num2str(layoutInd)]),'CallbackProperties');
        set(jMenuItem,'ActionPerformedCallback',{@changeLayout,layoutInd});
        myIcon = fullfile(pwd,'icons',['layout' num2str(layoutInd) '.gif']);
        jMenuItem.setIcon(javax.swing.ImageIcon(imageToolkit.createImage(myIcon)));
        jMenuItem.setBackground(color);
    end
     
    jToolbar.revalidate;

    I think I’ve narrowed it down that the following line of code is what is causing it to crash:

    jLayout = get(hLayout,'JavaContainer');

    Any suggestions on how to remedy this??

    Thanks!

  6. Kees de Kapper says:

    Dear Yair,

    Thank you for your extensive descriptions.
    However, I was wondering if it is possible to add icons to the jMenuItem in the uitogglesplittool or uisplittool?
    And secondly, is there a straight forward method to obtain the index of the selected jMenuItem.

    Many thanks for your consideration.
    All the Best,
    Kees

Leave a Reply

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