function h=multibar(msg,title,x)
% MULTIBAR Multi level progress bar with estimated time remaining
% H = MULTIBAR(MSG,TITLE) creates and displays a multi level progress
% bar with alphanumeric progress percentage and estimated time
% time remaining. MSG is a cell array of strings with multiple user input
% typically to distinguish what process is going to be monitored, and
% TITLE is an optional figure name. The figure handle H is
% returned.
%
% MULTIBAR(H,LEVEL,X) will update the length of the progress bar for the
% level in LEVEL, the percentage complete, and the estimated time remaining,
% where X is a fractional progress between 0 (initial) and 1 (complete).
%
% The estimated time remaining is linear using the initial time
% (when MULTIBAR is first opened), the current time, and the percent
% complete.
%
% Call MULTIBAR without arguments to see an example
%
% Version: 1.0
%
% Copyright 2005, Carlos Garcia
% cazurita@cantv.net
%
% Thanks to:
% Lars Gregersen (lg@2-control.com) and
% Chad English (cenglish@myrealbox.com)
if nargin==0
hm = multibar({'Setting up' 'Calculations' 'Cleaning up'},'Test: multibar');
H=multibar(hm, 2, i/100);
for i=1:100
multibar(H, 1, i/100), pause(100e-50);
end
for i=1:100
multibar(H, 2, i/100), pause(100e-50);
end
for i=1:100
multibar(H, 3, i/100), pause(100e-50);
end
close(H)
return
end
if ishandle(msg)
h = msg;
idx = title;
if ~strcmp(get(h,'tag'), 'multibar')
error('Handle is not a handle to a multibar window')
end
u = get(h, 'user');
set(u.ht(1:idx-1),'ForegroundColor',0*[1 1 1],'FontWeight','normal')
set(u.ht(idx),'ForegroundColor',[1 0 0],'FontWeight','bold')
set(u.ht(idx+1:end),'ForegroundColor',0.5*[1 1 1],'FontWeight','normal')
update_rate = 0.1;
if nargin==3
if x==0
%set(u.hbar,'visible','off')
else
if x>1
x = rem(x,1);
end
pause(10e-100)
set(u.hbar,'xdata',[0 0 x x 0])
%set(u.hbar,'visible','on')
end
progress=x;
inc = clock-u.inc; % Calculate time increment since last update
inc_secs = inc(3)*3600*24 + inc(4)*3600 + ...
inc(5)*60 + inc(6); % Convert the increment to seconds
if [inc_secs > update_rate] | [progress == 1] % Only update at update rate or 100% complete
u.inc = clock; % If updating, reset the increment clock
set(h,'user',u) % Update userdata with the new clock setting
tpast = clock-u.time; % Calculate time since timebar initialized
seconds_past = tpast(3)*3600*24 + tpast(4)*3600 + ...
tpast(5)*60 + tpast(6); % Transform passed time into seconds
estimated_seconds = seconds_past*(1/progress-1); % Estimate the time remaining in seconds
hours = floor(estimated_seconds/3600); % Calculate integer hours of estimated time
minutes = floor((estimated_seconds-3600*hours)/60); % Calculate integer minutes of estimated time
seconds = floor(estimated_seconds-3600*hours- ...
60*minutes); % Calculate integer seconds of estimated time
tenths = floor(10*(estimated_seconds - ...
floor(estimated_seconds))); % Calculate tenths of seconds (as integer)
%%%%%%%% END CALCULATE ESTIMATED TIME REMAINING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%% UPDATE ESTIMATED TIME AND PROGRESS TO TIMEBAR %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if progress > 1 % Check if input progress is > 1
time_message = ' Error! Progress > 1!'; % If >1, print error to estimated time
time_color = 'r'; % in red
else
if hours < 10; h0 = '0'; else h0 = '';end % Put leading zero on hours if < 10
if minutes < 10; m0 = '0'; else m0 = '';end % Put leading zero on minutes if < 10
if seconds < 10; s0 = '0'; else s0 = '';end % Put leading zero on seconds if < 10
time_message = strcat(h0,num2str(hours),':',m0,...
num2str(minutes),':',s0,num2str(seconds),...
'.',num2str(tenths),' (hh:mm:ss.t)'); % Format estimated time as hh:mm:ss.t
time_color = 'k'; % Format estimated time text as black
end
set(u.text(2),'string',time_message,...
'foregroundcolor',time_color); % Update estimated time
set(u.text(3),'string',...
strcat(num2str(floor(100*progress)),'%')); % Update progress percentage
end
else
%set(u.hbar,'visible','off')
end
else
if ~iscell(msg) | ~ischar(title)
error('Wrong arguments to multibar')
end
winwidth = 300; % Width of timebar window
winheight = 75;
dim=[300 length(msg)*25+40+25];
c = get(0,'defaultUicontrolBackgroundColor');
h = figure('pos',gui_center(dim),...
'menubar','none',...
'numbertitle','off',...
'name',title,...
'color',c,...
'resize','off',...
'tag','multibar');
for i=1:length(msg)
u.ht(i) = uicontrol(h,...
'style','text',...
'pos',[10 dim(2)-i*25-10 dim(1)-20 23],...
'hor','left',...
'backgroundcolor',c,...
'ForegroundColor',0.5*[1 1 1],...
'string',[num2str(i) '. ' msg{i}]);
end
u.ax = axes('parent',h,...
'units','pixels',...
'pos',[10 dim(2)-length(msg)*25-30 dim(1)-20-40 20],...
'xlim',[0 1],...
'box','on',...
'color',[1 1 1],...
'xtick',[],'ytick',[]);
u.hbar = patch([0 0 0 0 0],[0 1 1 0 0],'r');
% set(u.hbar,'visible','off')
est_text = 'Estimated time remaining: ';
u.text(1) = uicontrol(h,'style','text',... % Prepare static estimated time text
'pos',[10 5 dim(2)-20 20],... % Set the textbox position and size
'hor','left',... % Left align the text in the textbox
'backgroundcolor',c,... % Set the textbox background color
'foregroundcolor',0*[1 1 1],... % Set the text color
'string',est_text); % Set the static text for estimated time
u.text(2) = uicontrol(h,'style','text',... % Prepare estimated time
'pos',[135 5 155 20],... % Set the textbox position and size
'hor','left',... % Left align the text in the textbox
'backgroundcolor',c,... % Set the textbox background color
'foregroundcolor',0*[1 1 1],... % Set the text color
'string',''); % Initialize the estimated time as blank
u.text(3) = uicontrol(h,'style','text',... % Prepare the percentage progress
'pos',[dim(1)-40 dim(2)-length(msg)*25-33 25 20],...
'hor','right',... % Left align the text in the textbox
'backgroundcolor',c,... % Set the textbox background color
'foregroundcolor',0*[1 1 1],... % Set the textbox foreground color
'string',''); % Initialize the progress text as blank
% 'pos',[dim(2)-35 dim(1)-50 25 20],... % Set the textbox position and size
u.time = clock; % Record the current time
u.inc = clock; % Set incremental clock to current time
set(h, 'user', u)
end
if nargout==0
clear h
end
% --------
function pos=gui_center(pos)
% Changes pos parameter to make the GUI appear in the center of the screen
%
% pos=gui_center(pos)
sc = get(0,'screensize');
if length(pos)==4
pos = [(sc(3)-pos(3))/2 (sc(4)-pos(4))/2 pos(3:4)];
elseif length(pos)==2
pos = [(sc(3)-pos(1))/2 (sc(4)-pos(2))/2 pos(1:2)];
else
error('Wrong type or length for pos')
end