- Undocumented Matlab - https://undocumentedmatlab.com -
uisplittool & uitogglesplittool callbacks
Posted By Yair Altman On December 15, 2010 | 3 Comments
Last week, I presented the undocumented uisplittool and uitogglesplittool functions and showed how they can be added to a Matlab figure toolbar. Today I wish to conclude this topic by explaining how these controls can be customized with user-defined callbacks and pop-up menus.
Both uisplittool and uitogglesplittool have a Callback property, in addition to the standard ClickedCallback property that is available in uipushtools and uitoggletools.
The standard ClickedCallback is invoked when the main button is clicked, while Callback is invoked when the narrow arrow button is clicked. uitogglesplittool, like uitoggletool, also has settable OnCallback and OffCallback callback properties.
The accepted convention is that ClickedCallback should invoke the default control action (in our case, an Undo/Redo of the topmost uiundo action stack [1]), while Callback should display a drop-down of selectable actions.
While this can be done programmatically using the Callback property, this functionality is already pre-built into uisplittool and uitogglesplittool for our benefit. To access it, we need to get the control’s underlying Java component.
Accessing the underlying Java component is normally done using the findjobj utility [2], but in this case we have a shortcut: the control handle’s hidden JavaContainer property that holds the underlying com.mathworks.hg.peer.SplitButtonPeer (or .ToggleSplitButtonPeer) Java reference handle. This Java object’s MenuComponent property returns a reference to the control’s drop-down sub-component (which is a com.mathworks.mwswing.MJPopupMenu object):
>> jUndo = get(hUndo,'JavaContainer')
jUndo =
com.mathworks.hg.peer.SplitButtonPeer@f09ad5
>> jMenu = get(jUndo,'MenuComponent') % or: =jUndo.getMenuComponent
jMenu =
com.mathworks.mwswing.MJPopupMenu[Dropdown Picker ButtonMenu,...]
Let’s add a few simple textual options:
jOption1 = jMenu.add('Option #1');
jOption1 = jMenu.add('Option #2');
set(jOption1, 'ActionPerformedCallback', 'disp(''option #1'')');
set(jOption2, 'ActionPerformedCallback', {@myCallbackFcn, extraData});
Let’s now use this information, together with last year’s set of articles [3] about Matlab’s undocumented uiundo functionality, to generate a complete and more realistic example, of undo/redo toolbar buttons.
Undo and redo are actions that are particularly suited for uisplittool, since its main button enables us to easily undo/redo the latest action (like a simple toolbar button, by clicking the main uisplittool button) as well as select items from the actions drop-down (like a combo-box, by clicking the attached arrow button) – all this using a single component.
% Display our GUI
hEditbox = uicontrol('style','edit', 'position',[20,60,40,40]);
set(hEditbox, 'Enable','off', 'string','0');
hSlider = uicontrol('style','slider','userdata',hEditbox);
set(hSlider,'Callback',@test_uiundo);
% Display the figure toolbar that was hidden by the uicontrol function
set(gcf,'Toolbar','figure');
% Add the Undo/Redo buttons
hToolbar = findall(gcf,'tag','FigureToolBar');
hUndo = uisplittool('parent',hToolbar);
hRedo = uitogglesplittool('parent',hToolbar);
% 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'')');
% Re-arrange the Undo/Redo buttons
jToolbar = get(get(hToolbar,'JavaContainer'),'ComponentPeer');
jButtons = jToolbar.getComponents;
for buttonIdx = length(jButtons)-3 : -1 : 7 % end-to-front
jToolbar.setComponentZOrder(jButtons(buttonIdx), buttonIdx+1);
end
jToolbar.setComponentZOrder(jButtons(end-2), 5); % Separator
jToolbar.setComponentZOrder(jButtons(end-1), 6); % Undo
jToolbar.setComponentZOrder(jButtons(end), 7); % Redo
jToolbar.revalidate;
% Retrieve redo/undo object
undoObj = getappdata(gcf,'uitools_FigureToolManager');
if isempty(undoObj)
undoObj = uitools.FigureToolManager(gcf);
setappdata(gcf,'uitools_FigureToolManager',undoObj);
end
% Populate Undo actions drop-down list
jUndo = get(hUndo,'JavaContainer');
jMenu = get(jUndo,'MenuComponent');
undoActions = get(undoObj.CommandManager.UndoStack,'Name');
jMenu.removeAll;
for actionIdx = length(undoActions) : -1 : 1 % end-to-front
jActionItem = jMenu.add(undoActions(actionIdx));
set(jActionItem, 'ActionPerformedCallback', @myUndoCallbackFcn);
end
jToolbar.revalidate;
% Drop-down callback function
function myUndoCallbackFcn(jActionItem,hEvent)
% user processing needs to be placed here
end % myUndoCallbackFcn
Categories: Figure window, Java, Medium risk of breaking in future versions, Stock Matlab function, Undocumented feature
Article printed from Undocumented Matlab: https://undocumentedmatlab.com
URL to article: https://undocumentedmatlab.com/articles/uisplittool-uitogglesplittool-callbacks
URLs in this post:
[1] uiundo action stack: http://undocumentedmatlab.com/blog/uiundo-matlab-undocumented-undo-redo-manager/
[2] findjobj utility: http://undocumentedmatlab.com/blog/findjobj-find-underlying-java-object/
[3] set of articles: http://undocumentedmatlab.com/blog/tag/uiundo/
[4] below: http://undocumentedmatlab.com/blog/uisplittool-uitogglesplittool-callbacks/#respond
[5] uisplittool & uitogglesplittool : https://undocumentedmatlab.com/articles/uisplittool-uitogglesplittool
[6] Figure toolbar components : https://undocumentedmatlab.com/articles/figure-toolbar-components
[7] Matlab callbacks for Java events : https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events
[8] Enabling user callbacks during zoom/pan : https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan
[9] Matlab callbacks for Java events in R2014a : https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events-in-r2014a
[10] Uicontrol callbacks : https://undocumentedmatlab.com/articles/uicontrol-callbacks
Click here to print.
Copyright © Yair Altman - Undocumented Matlab. All rights reserved.
3 Comments To "uisplittool & uitogglesplittool callbacks"
#1 Comment By Chris On July 30, 2011 @ 19:21
Hello Yair,
this site is great!
I am using the togglesplittool in my GUI. First I had problems, Matlab 2010a shutting down. I was able to solve this by putting a “pause(0.01)” before calling “get(hUndo,’JavaContainer’)”.
You know a way to put a sign like you have on uimenus by setting the ‘checked’-property to ‘on’?
Greetings Chris
#2 Comment By Yair Altman On July 30, 2011 @ 23:32
@Chris – I don’t follow you: where do you want the check sign and under which conditions do you want it to appear/disappear?
#3 Comment By Chris On July 31, 2011 @ 00:19
Exactly, i give different options the user can choose from the togglesplittool associated drop-down-menu. After choosing one can click the togglebutton. Now it would be nice if the user can see the actually selected option. This i would like to do by putting a sign check to the last selected option from the drop-down-menu. I hope you got what i mean?