what is the replacement for uisplittool?

Hello there,
I maintain code for our lab group and someone posted a warning that uisplittool is undocumented and will be removed in future versions of MATLAB.
I was wondering what would be the equivalent command that should be used instead to maintain operability.
Raw error:
uisplittool is an un-documented built-in Matlab tool for handling graphics for toolbars in Matlab. The warning indicates it's deprecated.

3 Comments

Hi Christian,
Could you let me know the use of uisplittool in your case? Are you using it to insert an image-icon in the toolbar or for the dropdown?
It is used in the dropdown case instead of inserting an image-icon in the toolbar
```
case 'dropdown'
hm = uisplittool(toolbar,'tooltipstring',row{colm.ToolTip});
set(hm,'separator',row{colm.Separator});
```
I looked more into the specific function of it. It is a dropdown on an image that is in the toolbar. This code was written before the UI tools that were introduced in the R2016a release.

Sign in to comment.

 Accepted Answer

Hi Christian,
From the provided details, I gather that you are looking for an alternative to uisplittool as it is an un-documented built-in MATLAB tool, which will be removed in future releases. You are using this tool to create a selectable dropdown on an image in the toolbar.
It is important to note that the uisplittool creates a separate button in the toolbar, which is essentially a button split into two sections. One section (image icon) performs an action immediately (primary action), and the other section displays a dropdown arrow that, when clicked, reveals a dropdown menu with additional options (secondary actions).
While there's no direct alternative to uisplittool in MATLAB, there's a promising workaround using uipushtool. This tool, although not designed for splitting into two parts, can simulate the behavior by inserting an image icon in the toolbar. It reveals a context menu (dropdown) below the toolbar when clicked.
You can refer to the provided workaround to get more clarity on the implementation:
% Create a figure and add a toolbar to it
fig = figure('Toolbar', 'none', 'MenuBar', 'none', 'Name', 'Custom Toolbar Dropdown', 'WindowButtonDownFcn', @(src, event)hideContextMenu(src));
tb = uitoolbar(fig);
% Load the icon (e.g. greenarrowicon)
icon = fullfile(matlabroot,'/toolbox/matlab/icons/greenarrowicon.gif');
[cdata,map] = imread(icon);
% Convert white pixels into a transparent background
map(map(:, 1) + map(:, 2) + map(:, 3) == 3) = NaN;
% Convert into 3D RGB-space
cdataRedo = ind2rgb(cdata,map);
% Create a push tool in the toolbar
pt = uipushtool(tb,'cdata',cdataRedo,'TooltipString','Dropdown Menu', 'Separator', 'on');
% Set the callback for the click on image-icon
pt.ClickedCallback = @(src, event)dropdownClicked(src, event, fig);
% Callback for click on image-icon
function dropdownClicked(~, ~, fig, flag)
% Define items for the dropdown
items = {'Movement Function', 'Transformation Function', 'Experiment Code'};
% Create a context menu (acts as dropdown)
cm = uicontextmenu(fig);
% Populate the context menu with items
for i = 1:length(items)
% Different callback function can be made for each option of
% the context menu. Here, selction option is printed
uimenu(cm, 'Label', items{i}, 'Callback', @(s,e)disp(['Selected Option: ', items{i}]));
end
% Sample position of the context-menu
dropdownPos = [15, 420];
cm.Position = dropdownPos;
% Make the context menu visible
cm.Visible = 'on';
end
function hideContextMenu(src)
% Hide the context menu by setting the figure's UIContextMenu to none
src.UIContextMenu = [];
end
It is worth highlighting that the above approach allows for a primary action (displaying the context menu) and secondary actions (the items within the context menu) from a single toolbar button.
For more information, you can visit the following documentation of uipushtool and uicontextmenu:
I trust this explanation addresses your query.
Thanks

6 Comments

Thank you for providing a MWE! If we wanted to augment this answer and provide the user with an indication like that this button was indeed a drop-down menu, how would we go about inserting a small down arrow, similar to the ones in the original UI image?
Would that involve manipulating the original image? Or is there a way to programmatically append a region onto the image that encodes a small down arrow?
Thank you for your help. I've added a small black downward facing triangle to indicate that this is a dropdown. I am including the code here.
% Create a figure and add a toolbar to it
fig = figure('Toolbar', 'none', 'MenuBar', 'none', 'Name', 'Custom Toolbar Dropdown', 'WindowButtonDownFcn', @(src, event)hideContextMenu(src));
tb = uitoolbar(fig);
% Load the icon (e.g. greenarrowicon)
icon = fullfile(matlabroot,'/toolbox/matlab/icons/greenarrowicon.gif');
[cdata,map] = imread(icon);
% Convert white pixels into a transparent background
map(map(:, 1) + map(:, 2) + map(:, 3) == 3) = NaN;
% Convert into 3D RGB-space
cdataRedo = ind2rgb(cdata,map);
% Create a blank image of the same size as the original image with all values set to NaN
arrowImg = NaN(size(cdataRedo));
% Draw a black triangle in the middle of the image
arrowHeight = size(cdataRedo, 1)/4; % Height of the arrow is 1/4 the height of the original image
arrowWidth = size(cdataRedo, 2); % Width of the arrow is the same as the width of the original image
startRow = size(cdataRedo, 1)/2 - arrowHeight/2; % Start drawing the triangle from the middle of the image
for i = 1:arrowHeight
arrowImg(startRow+arrowHeight-i, arrowWidth/2-i+1:arrowWidth/2+i-1) = 0; % Draw each row of the triangle
end
% Append the arrow image to the right of the original image
cdataRedo = horzcat(cdataRedo, arrowImg);
% Create a push tool in the toolbar
pt = uipushtool(tb,'cdata',cdataRedo,'TooltipString','Dropdown Menu', 'Separator', 'on');
% Set the callback for the click on image-icon
pt.ClickedCallback = @(src, event)dropdownClicked(src, event, fig);
function dropdownClicked(~, ~, fig, flag)
% Define items for the dropdown
items = {'Movement Function', 'Transformation Function', 'Experiment Code'};
% Create a context menu (acts as dropdown)
cm = uicontextmenu(fig);
% Populate the context menu with items
for i = 1:length(items)
% Different callback function can be made for each option of
% the context menu. Here, selction option is printed
uimenu(cm, 'Label', items{i}, 'Callback', @(s,e)disp(['Selected Option: ', items{i}]));
end
% Sample position of the context-menu
dropdownPos = [15, 420];
cm.Position = dropdownPos;
% Make the context menu visible
cm.Visible = 'on';
end
function hideContextMenu(src)
% Hide the context menu by setting the figure's UIContextMenu to none
src.UIContextMenu = [];
end
Glad I could help! Cheers!!
I like this clever answer by @Shivam, and I like @Christian's modification of including the black downward arrow to indicate a drop-down pushtool.
I've made a few additional modifications that may be useful, including:
  • creating the uicontextmenu once and setting its visibility as needed (instead of creating a new uicontextmenu each time the pushbutton is clicked and never deleting it)
  • setting the uicontextmenu Position adaptively, i.e., making the uicontextmenu appear at the top of the figure (regardless of the figure's height) and with its left edge in the middle of the pushtool (regardless of the pushtool's location in the toolbar)
  • maintaining 16x16 icon size, including the black arrow (so the green arrow is not cut off on the left) by placing the black arrow in the lower-right corner of the image
Here's an example with two dropdown pushtools amongst several non-dropdown pushtools, to illustrate the uicontextmenu positioning:
% Create a figure and add a toolbar to it
fig = figure('Toolbar', 'none', 'MenuBar', 'none', 'Name', 'Custom Toolbar Dropdown');
tb = uitoolbar(fig);
% Load the icon (e.g. greenarrowicon)
icon = fullfile(matlabroot,'/toolbox/matlab/icons/greenarrowicon.gif');
[cdata,map] = imread(icon);
% Convert white pixels into a transparent background
map(all(map==1,2),:) = NaN;
% Convert into 3D RGB-space
cdataRedo = ind2rgb(cdata,map);
% store the original cdata (for non drop-down pushtools)
cdataRedo_original = cdataRedo;
% Draw a black triangle in the lower-right corner of the image
[m,n,~] = size(cdataRedo);
startCol = n-m/4+1;
for i = 1:m/4
cdataRedo(m-i+1, startCol-i+1:startCol+i-1, :) = 0; % Draw each row of the triangle
end
% Define items for the dropdown
items = {'Movement Function', 'Transformation Function', 'Experiment Code'};
% Create a context menu (acts as dropdown)
cm = uicontextmenu(fig);
% Populate the context menu with items
for i = 1:length(items)
% Different callback function can be made for each option of
% the context menu. Here, selction option is printed
uimenu(cm, 'Label', items{i}, 'Callback', @(s,e)disp(['Selected Option: ', items{i}]));
end
% Create a "dropdown" push tool in the toolbar
pt = uipushtool(tb,'cdata',cdataRedo,'TooltipString','Dropdown Menu');
% Set the callback for the click on image-icon
pt.ClickedCallback = {@dropdownClicked,fig,tb,cm};
% Create some other push tools in between
uipushtool(tb, 'CData', cdataRedo_original);
uipushtool(tb, 'CData', cdataRedo_original);
uipushtool(tb, 'CData', cdataRedo_original);
% Create another "dropdown" push tool in the toolbar
pt = uipushtool(tb,'cdata',cdataRedo,'TooltipString','Dropdown Menu', 'Separator', 'on');
% Set the callback for the click on image-icon
pt.ClickedCallback = {@dropdownClicked,fig,tb,cm};
% Set the figure's WindowButtonDownFcn to hide the contextmenu
fig.WindowButtonDownFcn = @(src, event)hideContextMenu(cm);
% Callback for click on image-icon
function dropdownClicked(src,~,fig,tb,cm)
% Position the context-menu
dropdownPos = [get_x_position(tb,src), fig.Position(4)];
cm.Position = dropdownPos;
% Make the context menu visible
cm.Visible = 'on';
end
function hideContextMenu(cm)
cm.Visible = 'off';
end
function x = get_x_position(tb,b)
ch = tb.Children(end:-1:1);
idx = find(ch==b,1);
sep = strcmp(get(ch(1:idx),'Separator'),'on');
x = 24*idx+4*nnz(sep)-12;
end
Those are useful and cool changes @Voss. On my machine, the dropdown's left edge is aligned with the center of the button but only for the first button. The last button's left edge is flush with the dropdown's left edge unfortunately. I don't know if it has anything to do with the separator line or how to make thoes consistent
Thank you!
You can modify this line to adjust the x position of the context menu:
x = 24*idx+4*nnz(sep)-12
In case it's not clear what that's doing, it's assuming each button is 24 pixels wide and each separator is 4 pixels wide (and the -12 is to center it on the button by subtracting half the width). I don't know a way to determine what those pixel values really are, so I just used trial and error to see what worked on my system; they're probably a little different on your system.
I think you're right that it does have to do with the separator. Turn the separator off and see if it lines up properly. If so, then you only need to increase the 4. If not, then you may need to adjust the 24 and the 4 (and change the -12 to minus half the button width you find).

Sign in to comment.

More Answers (0)

Categories

Find more on Interactive Control and Callbacks in Help Center and File Exchange

Products

Release

R2022a

Asked:

on 4 Mar 2024

Commented:

on 22 Mar 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!