function [] = GUI_39()
% Demonstrate use of nested functions for callbacks and other functions.
% Notice here that there is no need to extract S from varargin in each
% function because all callback functions are nested in the main function
% and therefore have access to the structure S.
% User can draw whatever is desired, and change colors by right-clicking in
% the axes window. When the drawing is complete, click the Save-As menu to
% save the file in one of three image formats.
%
%
% Suggested exercise: Add ability to interactively delete data points.
%
%
% Author: Matt Fig
% Date: 7/30/2009
S.COL = [0 0 1]; % Start with blue.
S.LST = {[],[0 0 1],[1 0 0],[0 .9 0],[.9 .9 0],[0 0 0]}; % List of colors.
S.FMT = {[],'jpg','png','bmp'}; % List of file formats.
S.fh = figure('units','pixels',...
'position',[300 300 400 400],...
'menubar','none',...
'name','GUI_39',...
'numbertitle','off',...
'resize','off');
S.ax = axes('units','pixels',...
'position',[20 20 360 350],...
'Xlim',[0 1],...
'YLim',[0 1],...
'drawmode','fast');
S.cm = uicontextmenu;
% Define the different color menus. We could define as many as we like.
% Each color has it's corresponding RGB values in S.LST. Note that the
% first cell in S.LST should be kept empty. (See um_call)
S.um(1) = uimenu(S.cm,'label','Color'); % First menu seen on right-click
S.um(2) = uimenu(S.um(1),'label','Blue'); % The rest are seen as submenus.
S.um(3) = uimenu(S.um(1),'label','Red');
S.um(4) = uimenu(S.um(1),'label','Green');
S.um(5) = uimenu(S.um(1),'label','Yellow');
S.um(6) = uimenu(S.um(1),'label','Black');
set(S.um(2:6),'callback',@um_call) % The callback for 5 uimenus.
% This next one will select from a wider palette.
S.um(7) = uimenu(S.um(1),'label','Other','callback',{@um7_call});
% Now we create a menu for the figure itself.
S.fm = uimenu(S.fh,'label','Save As');
S.fm(2) = uimenu(S.fm(1),'label','jpg');
S.fm(3) = uimenu(S.fm(1),'label','png');
S.fm(4) = uimenu(S.fm(1),'label','bmp');
set(S.fm(2:4),'callback',{@fm_call}) % To save the drawing.
axis([0,1,0,1]) % This locks the axes limits to avoid auto-rescaling.
set(S.ax,'xticklabel',[],'yticklabel',[],'xtick',[],'ytick',[]) % Neaten.
% Set the uicontextmenu to point to the axes.
set(S.ax, 'buttondownfcn',@ax_bdfcn,'uicontextmenu',S.cm)
hold on, box on % So that we don't overwrite with each new point drawn.
set(S.fh,'windowbuttonupfcn', @fh_wbufcn);
function [] = ax_bdfcn(varargin)
% ButtonDownFcn for the axes.
% We only want to do something if left clicking.
if strcmp(get(S.fh,'selectiontype'),'normal')
% We want to plot dots as long as user holds down mouse button.
set(S.fh, 'windowbuttonmotionfcn', @fh_wbmfcn)
end
end
function [] = fh_wbmfcn(varargin)
% The windowbuttonmotionfcn for figure, while button is held only.
pt = get(S.ax, 'currentpoint');
plot(pt(1),pt(3),'.','buttondownfcn',@ax_bdfcn,'color',S.COL);
end
function [] = fh_wbufcn(varargin)
% WindowButtonUpFcn for the figure.
% We want to stop drawing dots when user lets mouse button up.
set(S.fh, 'windowbuttonmotionfcn', '');
end
function [] = um_call(varargin)
% Callback for the uicontextmenu 2:6.
S.COL = S.LST{varargin{1}==S.um}; % Set the current color.
end
function [] = um7_call(varargin)
% Callback for the uicontextmenu number 7.
c = uisetcolor(); % Call the MATLAB color-getter.
S.COL = c; % Set the current color.
end
function [] = fm_call(varargin)
% Callback for the figure menu.
N = inputdlg('Enter a file name.','FileName'); % Get a name.
F = getframe(S.fh,get(S.ax,'position')+[1 1 -2 -2]); % Only want to get axes.
FMT = S.FMT{varargin{1}==S.fm}; % User's format choice.
imwrite(F.cdata,[N{1},'.',FMT],FMT) % Write the image.
end
end