function [P] = guidegetter(name,newfname,varargin)
%GUIDEGETTER create M-file GUI which duplicates the layout of a GUIDE GUI.
% This function reproduces the basic layout of a GUIDE created GUI,
% including the positions of all the GUI elements that are created with
% GUIDE, except active-X controls (uicontainers). All callbacks and other
% properties are not copied, only the essentials necessary to reproduce
% the layout of a GUIDE GUI from a single M-File. Thus this tool
% is useful when one wants to create a GUI from a standalone M-file, but
% would like to use GUIDE for it's excellent ability to position the GUI
% objects within the GUI. The proper use of this tool is to use GUIDE to
% get the desired layout, then before any further editing is performed, use
% this tool to generate an M-file GUI which can be run to recreate the
% layout of the GUIDE GUI and form the basis for the rest of the project.
%
%Example:
% The following example illustrates the use of GUIDEGETTER by showing the
% three ways in which guidegetter can be called. For this example assume
% that a GUI has been built with GUIDE. The name of the GUI is: guidegui.
% When GUIDE created the GUI it made two files, an M-file called guidegui.m
% and a figure file named guidegui.fig. To create a stand alone M-file GUI
% that duplicates the layout of the GUIDE GUI, call GUIDEGETTER in one of
% three ways:
%
% 1. Call GUIDEGETTER without input arguments. A couple of dialog boxes
% will be generated to get the correct information. i.e.,
%
% guidegetter
%
% 2. Call GUIDEGETTER with the name of the GUIDE GUI only. A dialog box
% will be generated to get the name of the new M-File GUI. i.e.,
%
% guidegetter('guidegui')
%
% A dialog box will pop up asking for the name of the new M-file to be
% created. Enter the name into the dialog box with no quotes, spaces
% or file extension. A default name (mygui) will appear as an example.
%
% 3. Call GUIDEGETTER with both the name of the GUIDE GUI and the name of
% the M-file GUI to be created. The GUIDE GUI name is first. This is
% quickest since no dialog boxes are created. i.e.,
%
% guidegetter('guidegui','mygui')
%
% Most objects created by the M-file GUI will be labeled according to
% the handle names in the M-file. This allows one to begin writing
% callbacks and changing other properties without having to guess which GUI
% object is created by which line in the M-file. All units are normalized.
%
% P = GUIDEGETTER, when called with any of the three methods above,
% returns a structure which contains properties of all the GUI elements
% including: the object's names, their parent's names, their positions,
% their backgroundcolors (if any), and their uicontextmenus (if any).
%
% Request:
% The M-file GUI generated by GUIDEGETTER will include a comment line that
% acknowledges the use of GUIDEGETTER. If the intent is to distribute the
% M-file GUI on the FEX it is requested, but not demanded, that this line
% be kept somewhere in the documentation. This will allow those who use
% your GUI to become aware of GUIDEGETTER. Thank you.
%
% Tested on version 6.5, and 2006a, created on version 2007a.
%
% Author: Matt Fig
% Contact: popkenai@yahoo.com
% Post Date: June 02 2008 revised to add uicontextmenus June 13 2008
% If you are reading this, I assume you are interested in the coding of
% this file. Please help me by making useful criticisms of my code through
% the above email. I am not a programmer by training, so my feelings won't
% get hurt and you may help me make the code better. Thank you.
% First some argument checking.
switch nargin
case 0 % User wants to use the dialogs to get files.
d = dir; % Get a listing of the current directory.
str = {d.name}; % These are the choices.
idx = regexp(str,'.fig'); % Find the figure files.
str = str(~cellfun('isempty',idx)); % Get the figure files.
if ~isempty(str)
[s,v] = listdlg('PromptString',['Select the GUIDE GUI ',...
'figure file:'],'SelectionMode','single',...
'ListString',str,'listsize',[200 80],'name',...
'GUI figure file name');
else
error('There are no figure files in the current directory.')
end
if v
name = str{s}(1:end-4); % Take off the .fig.
else % User hit cancel on the first dialog box.
if nargout == 1, P = []; end
return
end
hf = openfig(name,'new','invisible');
newfname = inputdlg('Enter the name of the new M-file:',...
'New M-file',1,{'mygui'}); % Ask for new name.
case 1
try
hf = openfig(name,'new','invisible');
catch
error('%s\n%s',['Error opening figure. Verify file exists',...
' in current directory,'],...
'or try GUIDEGETTER without inputs. See help.')
end
newfname = inputdlg('Enter the name of the new M-file',...
'New filename',1,{'mygui'}); % Get new name.
case 2
hf = openfig(name,'new','invisible');
otherwise
error('Incorrect number of input arguments. See help.');
end % End of basic input argument checking.
if isempty(newfname)
if nargout == 1, P = []; end
return % User hit cancel on the second dialog box.
elseif iscell(newfname) % Inputdlg returns a cell array.
newfname = newfname{1};
end
if sum(~cellfun('isempty',regexp(newfname,{'\.','\s'},'ONCE')))
error('Improper file name entered, see example in help.');
end
set(hf,'units','normalized'); % For uniformity.
H = findobj(hf); % Get all the children of the figure.
lngth = length(H);
if lngth == 1 % User passed in an empty figure.
if nargout == 1, P = []; end
disp(' An empty figure was passed. New M-file not created.')
return
end
% p is a structure that stores the necessary properties.
p.oh = H(:); % Handles to all GUI objects
p.ph = get(H(:),'parent'); % Handles to all parents.
p.clss = cell(lngth,1); % The class of all objects: 'type' or 'style'.
p.onm = cell(lngth,1); % The name of all objects.
p.pnm = cell(lngth,1); % The name of all parents.
p.opos = cell(lngth,1); % The position of all objects.
p.obgc = cell(lngth,1); % The object's background color, when applicable.
[p.uicn{1:lngth}] = deal('[]'); % Object's uicontextmenu, initialized.
% Next set the figure's name, parent, and position.
p.onm{1} = 'hf'; p.pnm{1} = 0; p.opos{1} = get(hf,'position');
%This structure is used for labeling the handles in the new M-file.
cnt = struct('edit',0,'text',0,'uipanel',0,'slider',0,'axes',0,'uimenu',...
0,'listbox',0,'checkbox',0,'radiobutton',0,'popupmenu',0,...
'togglebutton',0,'frame',0,'uibuttongroup',0,'pushbutton',0,...
'uicontextmenu',0);
fl = fopen([newfname,'.m'],'w+t'); % Open the new file for writting.
fwrite(fl,sprintf('%s\n',['function [] = ',newfname,'()'])); % First line.
fwrite(fl,sprintf('%s\n%s\n',['% The basic layout of this GUI was made',...
' with the help of guidegetter,'],['% available on the File '...
'Exchange at Mathworks.com'])); % The acknowledgement line.
% Next create the line for the figure declaration.
fwrite(fl,sprintf('\n%s',['hf = figure(','''units'',','''normalized''',...
',''position'',',mat2str(get(hf,'position'),3),',''menubar'',',...
'''none''',',''name'',','''',newfname,'''',',''numbertitle'',',...
'''off''',',''color'',',mat2str(get(hf,'color'),3),');']));
for ii=2:lngth % Create most of the rest of the structure p.
try
stl = get(p.oh(ii),'style'); % Used in writing to the file.
p.clss{ii} = 'style'; % Used to pass to the switch in writer.
cnt.(stl) = cnt.(stl) + 1; % Increment the counter for this style.
p.onm{ii} = [stl,num2str(cnt.(stl))];
catch
p.clss{ii} = 'type'; % The object has no 'style' property.
try
get(p.oh(ii),'SelectedObject'); % Find if it's a uibuttongroup.
typ = 'uibuttongroup';
catch
typ = get(p.oh(ii),'type'); % Not a uibuttongroup.
end
cnt.(typ) = cnt.(typ) + 1; % Increment the counter for this type.
p.onm{ii} = [typ,num2str(cnt.(typ))]; % Name the object.
end
try
set(p.oh(ii),'units','normalized'); % Some don't have units.
catch
end
p.opos{ii} = get(p.oh(ii),'position'); % The object's position.
if strfind(p.clss{ii},'style') % Only these need a backgroundcolor.
p.obgc{ii} = get(p.oh(ii),'backgroundcolor');
end
p.pnm{ii} = p.onm{find(p.ph{ii}==p.oh(:))}; % Find parent's name.
end
% Uicontextmenu's must be written first after figure declaration, so sort.
idxu = strmatch('uicontextmenu',p.onm)'; % Find the uicontextmenus.
idxf = strmatch('frame',p.onm)'; % Find the frames, to be written next.
ord = 1:length(p.onm); % Get a generic ordering.
ord([1 idxu idxf]) = []; % Send these elements to oblivion.
ord = [idxu,idxf,ord]; % Order in which the objects will be written.
for jj = ord
% We have to fill p.uicn here because now the p.onm is full.
try
p.uicn{jj} = p.onm{find(p.oh(:) == get(p.oh(jj),'uicontextmenu'))};
catch
end
writer(p.clss{jj},p.onm{jj},p.pnm{jj},p.opos{jj},p.obgc{jj},...
p.uicn{jj},fl); % Write this line in the new M-file.
end
close(hf) % Close the GUIDE GUI.
fclose(fl); % Close the new M-file.
if nargout == 1 % User wants the structure.
% Handles useless, figure is closed. Rename fields for readability.
P.objname = p.onm;
P.parentname = p.pnm;
P.objposition = p.opos;
P.objbackgroundcolor = p.obgc;
P.objuicontextmenu = p.uicn';
end
function [] = writer(clss,onm,pnam,opos,obgc,ouicn,fl)
% Subfunction to GUIDEGETTER. Writes to file the element declarations.
% clss is 'style' or 'type'
% onm is the object's name.
% pnam is the object's parent's name.
% opos is the object's position.
% obgc is the object's backgroundcolor
% ouicn is the object's uicontextmenu.
% fl is the new file being written.
nstr = onm(1:regexp(onm,'\d+')-1); % Take off the number for declarations.
switch clss % GUI elements are of class 'type' or are of class 'style'.
case 'style'
str = [onm,' = ','uicontrol','(',pnam,',''style'',','''',nstr,...
'''',',''units'',','''normalized''',',''position'',',...
mat2str(opos,3),',''string'',','''',onm,'''',...
',''backgroundcolor'',',mat2str(obgc,3),');'];
if ~strcmp('[]',ouicn) % Uicontextmenu?
str = [str(1:end-2), ',''uicontextmenu'',',ouicn,');'];
end
fwrite(fl,sprintf('\n%s',str));
case 'type' % Different 'types' have different properties.
switch nstr
case 'axes'
str = [onm,' = ',nstr,'(','''position'',',...
mat2str(opos,3),');'];
if ~strcmp('[]',ouicn) % Uicontextmenu?
str = [str(1:end-2), ',''uicontextmenu'',',ouicn,');'];
end
fwrite(fl,sprintf('\n%s',str));
case 'uimenu'
fwrite(fl,sprintf('\n%s',[onm,' = ',nstr,'(',pnam,...
',''position'',',mat2str(opos,3),',''label'',',...
'''',onm,'''',');']));
case {'uipanel','uibuttongroup'}
str = [onm,' = ',nstr,'(','''parent'',',pnam,...
',''units'',','''normalized''',',''position'',',...
mat2str(opos,3),',''title'',','''',onm,'''',');'];
if ~strcmp('[]',ouicn) % Uicontextmenu?
str = [str(1:end-2), ',''uicontextmenu'',',ouicn,');'];
end
fwrite(fl,sprintf('\n%s',str));
case 'uicontextmenu'
fwrite(fl,sprintf('\n%s',[onm,' = ',nstr,'(',...
'''position'',',mat2str(opos,3),');']));
otherwise
end
otherwise
end