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:
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'')'); |
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; |
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:
Thanks. I find this useful.
out of topic, but thank you for your efforts.
You are of great help to many Matlab practitioners!
Best regards
Dan
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?
@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.
[…] The idea here is to replace the standard toolbar “Open File” pushbutton with a new uisplittool button that will contain the MRU list in its picker-menu. […]
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:
I think I’ve narrowed it down that the following line of code is what is causing it to crash:
Any suggestions on how to remedy this??
Thanks!
I forgot to mention that if I go into debug mode and step through each line of code, then it works perfectly. When I let it run on its own is when it crashes. Not sure if that makes a difference.
Sounds like an EDT issue. Try adding drawnow and/or pause(0.1).
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
I am trying to do it using uipushtool since uisplittool is not supported anymore. I am able to insert the image icon in the toolbar, but not sure how to get the dropdown (trying to make it backward compatible to uisplittool). Here is the code:
Can someone help me making it function like uisplittool? I have the code written which is dependent on uisplittool, so need to make the new functionality backward compatible to it.
Thanks in advance.
which Matlab version are you using?