% EMBEDEDPROGRESSBAR An object-based progressbar, designed for tunability.
%
% EMBEDEDPROGRESSBAR intends to be a merge of all the previous
% progressbar that can be found on the FEX. Its two main features are:
%
% 1) It uses classes and objects, which also each embededprogressbar to
% be accessed and modified through get and set functions.
%
% 2) It can be embeded in an existing figure and moved around as desired
% (see below).
%
% INSTALL:
%
% Copy the folder @embededprogressbar in one of the folder which belongs
% to your Matlab path. Its subfolder should *not* be added to the path
% (like for every Matlab class).
%
% SYNTAX:
%
% epb = EMBEDEDPROGRESSBAR creates a new figure containing a new
% progressbar initialized with default values.
%
% epb = EMBEDEDPROGRESSBAR(property,val,...) allows to tune the new
% progressbar. Supported properties are:
%
% - VALUE (number between 0 and 1, default 0):
% Sets the initial value of the progression to val.
%
% - PARENT (figure handle, default 0, which creates a new figure):
% Sets the figure in which the embededprogressbar should appear.
%
% - TITLE (string, default empty string):
% When a new figure to embed the progress bar is created, sets its
% name to val.
%
% - STRING (string, default empty string, which does not display a title):
% Sets the title to be displayed on top of the progresssion bar. If set
% to non empty string, a percentage of the progression will be displayed
% next to this label.
%
% - TIMESTRING (string, default 'Estimated time remaining: '):
% If sets to non-empty string, val will be displayed below the progress
% bar and the estimated time remaining will be computed and displayed
% next to this label.
%
% - POSITION (a 4x1 array of whole number, default []):
% Sets the position of the progress bar with [xpos ypox width heigth].
% If val is equal to the empty matrix (the default), a position will be
% automatically computed depending on the size of the parent figure.
%
% - ABORTBUTTON (logical, default false):
% If set to true, an abort button will be displayed next to the progress
% bar, which will allow to handle abort events from the user.
%
% - ABORTFLAG (logical, default false):
% Will be set to true if the user click on the abort button.
%
%
% All of these properties can be modified after the creation of the
% progress bar by using a set/get syntax. Examples:
%
% % To update progression with current value:
% epb = embededprogressbar
% set(epb,'value',0.5)
%
% % To move an epb from one figure to another:
% h1 = figure;
% h2 = figure;
% epb = embededprogressbar('parent',h2)
% set(epb,'parent',h2)
%
% % To handle abort events from user:
% epb = embededprogressbar('AbortButton',true)
% % Now, press abort
% flagraised = get(epb,'AbortFlag')
% if flagraised, disp('User canceled operation.'); else, ...
% disp('Continuing computation.'); end;
%
%
% WARNING:
%
% I could not find a proper way to store a reference to the object
% (Matlab only works on copies, not on references when calling a
% subfunction or a callback), which was needed to handle the abort
% events. I ended up using a global variable (referentetoepb) shared
% between embededprogressbar.m, set.m and get.m. I welcome any
% suggestion to get rid of global variables.
%
%
% REQUIREMENTS:
%
% checkfield.m (can be found on the FEX).
% ------------------ INFO ------------------
% Author: Jean-Yves Tinevez
% Work address: Max-Plank Insitute for Cell Biology and Genetics,
% Dresden, Germany.
% Email: tinevez AT mpi-cbg DOT de
% November 2007;
% Permission is given to distribute and modify this file as long as this
% notice remains in it. Permission is also given to write to the author
% for any suggestion, comment, modification or usage.
% ------------------ BEGIN CODE ------------------
function epb = embededprogressbar(varargin)
default = struct(...
'Value',0,...
'Parent',0,...
'Title','',...
'String','',...
'TimeString','Estimated time remaining: ',...
'Position',[],...
'AbortButton',false,...
'AbortFlag', false, ...
... Following fields should be kept private
'ETR',0,...
'StartTime',0,...
'LastUpdate',0, ...
'StringHandle',0,...
'PatchHandle',0, ...
'BorderHandle',0, ...
'ETRTextHandle',0, ...
'ETRHandle',0, ...
'PercentHandle',0, ...
'AxesHandle',0, ...
'AbortButtonHandle',0, ...
'ID', 0 ...
);
% Did not find any other way ....
global referencetoepb
if nargin == 0
epb = class(default,'embededprogressbar');
getnewbar(epb);
referencetoepb{epb.ID} = epb;
return;
elseif nargin == 1 && isa(varargin{1},'embededprogressbar')
epb = varargin{1};
return
else
% create a new one
listfields = { ...
'Value',...
'Position',...
'Parent',...
'Title',...
'String', ...
'TimeString',...
'AbortButton' ...
};
testvalid = { ...
@(i) isreal(i) && i>=0 && i<=1, ...
@(i) length(i) == 4, ...
@ishandle, ...
@ischar,...
@ischar,...
@ischar, ...
@islogical ...
};
acceptablevalues = {
{}, ...
{}, ...
{}, ...
{}, ...
{}, ...
{}, ...
[true false] ...
};
% Put all properties in the new object
options = checkfield(varargin,listfields,testvalid,acceptablevalues,default);
epb = class(options,'embededprogressbar');
getnewbar(epb);
referencetoepb{epb.ID} = epb;
return
end % if nargin
% SUBFUNCTIONS
function getnewbar(opt)
nref = length(referencetoepb);
epb.ID = nref + 1;
if opt.Parent == 0
% No parent? Then we create it in a new figure
parentfigure = getnewfigure();
else
parentfigure = opt.Parent;
end
epb.Parent = parentfigure;
if isempty(opt.Position)
% No position specified? We make some out of the figure one
fpos = get(parentfigure,'Position');
if opt.AbortButton
pos = [10 25 fpos(3)-100 15];
else
pos = [10 25 fpos(3)-20 15];
end
else
pos = opt.Position;
end
epb.Position = pos;
epb.AxesHandle = axes(...
'parent',parentfigure,... % Set the progress bar parent to the figure
'units','pixels',... % Provide axes units in pixels
'pos',pos,... % Set the progress bar position and size
'xlim',[0 1],... % Set the range from 0 to 1
'visible','off',... % Turn off axes
'drawmode','fast'); % Draw faster (I dunno if this matters)
epb.BorderHandle = patch(...
'Parent', epb.AxesHandle,...
'XData', [1 0 0 1],... % Initialize X-coordinates for patch
'YData', [0 0 1 1],... % Initialize Y-coordinates for patch
'Facecolor', 'w',... % Set Color of patch
'EdgeColor', 'k',...
'EraseMode', 'normal' ); % Set Erase mode, so we can see progress image
value = epb.Value;
epb.PatchHandle = patch(...
'Parent', epb.AxesHandle,...
'XData', [0 value value 0 ],... % Initialize X-coordinates for patch
'YData', [0 0 1 1],... % Initialize Y-coordinates for patch
'Facecolor', 'r',... % Set Color of patch
'EraseMode', 'normal' ); % Set Erase mode, so we can see progress image
message = opt.String;
if ~isempty(message)
epb.StringHandle = uicontrol(parentfigure,'style','text',... % Prepare message text (set the style to text)
'pos',[pos(1) pos(2)+pos(4)+5 pos(3)-60 15],... % Set the textbox position and size
'hor','left',... % Center the text in the textbox
'Background',get(parentfigure,'Color'),...
'foregroundcolor','k',... % Set the text color
'string',message);
epb.PercentHandle = uicontrol(parentfigure,'style','text',... % Prepare the percentage progress
'pos',[pos(1)+pos(3)-40 pos(2)+pos(4)+5 40 15],... % Set the textbox position and size
'hor','right',... % Left align the text in the textbox
'Background',get(parentfigure,'Color'), ...
'foregroundcolor','k',... % Set the textbox foreground color
'string','0%');
end
epb.String = message;
timestr = opt.TimeString;
if ~ isempty(timestr)
epb.ETRTextHandle = uicontrol(parentfigure,'style','text',... % Prepare static estimated time text
'pos',[pos(1) pos(2)-20 pos(3) 15],... % Set the textbox position and size
'hor','left',... % Left align the text in the textbox
'Background',get(parentfigure,'Color'),...
'foregroundcolor','k',... % Set the text color
'string',timestr); % Set the static text for estimated time
epb.ETRHandle = uicontrol(parentfigure,'style','text',... % Prepare estimated time
'pos',[pos(1)+pos(3)-60 pos(2)-20 60 15],... % Set the textbox position and size
'hor','right',... % Left align the text in the textbox
'Background',get(parentfigure,'Color'),...
'foregroundcolor','k',... % Set the text color
'string','estimating...'); % Initialize the estimated time as blank
end
if opt.AbortButton
epb.AbortButtonHandle = uicontrol( ...
parentfigure, ...
'style','pushbutton' ,...
'pos', [pos(1)+pos(3)+10 pos(2)-7 50 30], ...
'string','Abort', ...
'callback',{@raiseabortflag,epb}...
);
end
% Set time of last update to ensure a redraw
epb.LastUpdate = clock - 1;
epb.StartTime = clock;
function progfig = getnewfigure()
% returns default figure
winwidth = 300; % Width of timebar window
winheight = 75; % Height of timebar window
screensize = get(0,'screensize'); % User's screen size [1 1 width height]
screenwidth = screensize(3); % User's screen width
screenheight = screensize(4); % User's screen height
winpos = [0.5*(screenwidth-winwidth), ...
0.5*(screenheight-winheight),...
winwidth, winheight]; % Position of timebar window origin
progfig = figure('menubar','none',... % Turn figure menu display off
'numbertitle','off',... % Turn figure numbering off
'position',winpos,... % Set the position of the figure as above
'resize','off',... % Turn of figure resizing
'tag','timebar'); % Tag the figure for later checking
if ~isempty(opt.Title)
set(progfig,'Name',opt.Title)
end
end % function getnewbar.getnewfigure
end % function getnewbar
function raiseabortflag(hObject,eventdata,epb)
set(epb,'AbortFlag',true);
set(hObject,'Enable','off');
end
end % main function