-
Notifications
You must be signed in to change notification settings - Fork 22
/
progressbar.m
182 lines (154 loc) · 4.91 KB
/
progressbar.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
function [timeleftstr] = progressbar(varargin)
persistent progdata lastupdate
% Get inputs
if nargin > 0
input = varargin;
ninput = nargin;
else
% If no inputs, init with a single bar
input = {0};
ninput = 1;
end
% Init reset flag
resetflag = false;
% Set reset flag if first input is a string
if ischar(input{1})
resetflag = true;
end
% Set reset flag if all inputs are zero
if input{1} == 0
% If the quick check above passes, need to check all inputs
if all([input{:}] == 0) && (length([input{:}]) == ninput)
resetflag = true;
end
end
% Set reset flag if more inputs than bars
if ninput > length(progdata)
resetflag = true;
end
% If reset needed, close figure and forget old data
if resetflag
progdata = []; % Forget obsolete data
end
% Figure out how many bars to draw
nbars = max(ninput, length(progdata));
% axes(axesHandle);
for ndx = 1:nbars
% % progdata(ndx).progaxes = axesHandle;
progdata(ndx).progpatch = patch('XData', [0 0 0 0],'YData', [0 0 1 1]);
progdata(ndx).progtext = text(0.99, 0.5, '', ...
'HorizontalAlignment', 'Right', ...
'FontUnits', 'Normalized', ...
'FontSize', 0.7 );
progdata(ndx).proglabel = text(0.01, 0.5, '', ...
'HorizontalAlignment', 'Left', ...
'FontUnits', 'Normalized', ...
'FontSize', 0.7 );
if ischar(input{ndx})
set(progdata(ndx).proglabel, 'String', input{ndx})
input{ndx} = 0;
end
% Set callbacks to change color on mouse click
% set(progdata(ndx).progaxes, 'ButtonDownFcn', {@changecolor, progdata(ndx).progpatch})
% set(progdata(ndx).progpatch, 'ButtonDownFcn', {@changecolor, progdata(ndx).progpatch})
% set(progdata(ndx).progtext, 'ButtonDownFcn', {@changecolor, progdata(ndx).progpatch})
% set(progdata(ndx).proglabel, 'ButtonDownFcn', {@changecolor, progdata(ndx).progpatch})
% Pick a random color for this patch
% changecolor([], [], progdata(ndx).progpatch)
set(progdata(ndx).progpatch, 'FaceColor', [0.3 0.3 0.3]);
% Set starting time reference
if ~isfield(progdata(ndx), 'starttime') || isempty(progdata(ndx).starttime)
progdata(ndx).starttime = clock;
end
end
% Set time of last update to ensure a redraw
lastupdate = clock - 1;
% end
% Process inputs and update state of progdata
for ndx = 1:ninput
if ~isempty(input{ndx})
progdata(ndx).fractiondone = input{ndx};
progdata(ndx).clock = clock;
end
end
% Enforce a minimum time interval between graphics updates
myclock = clock;
if abs(myclock(6) - lastupdate(6)) < 0.01 % Could use etime() but this is faster
return
end
% Update progress patch
for ndx = 1:length(progdata)
set(progdata(ndx).progpatch, 'XData', ...
[0, progdata(ndx).fractiondone, progdata(ndx).fractiondone, 0])
end
% Update progress text if there is more than one bar
if length(progdata) > 1
for ndx = 1:length(progdata)
set(progdata(ndx).progtext, 'String', ...
sprintf('%1d%%', floor(100*progdata(ndx).fractiondone)))
end
end
% Update progress figure title bar
if progdata(1).fractiondone > 0
runtime = etime(progdata(1).clock, progdata(1).starttime);
% timeleft = runtime;
timeleftstr = sec2timestr(runtime);
else
timeleftstr = 0;
end
% Force redraw to show changes
drawnow
% Record time of this update
lastupdate = clock;
% ------------------------------------------------------------------------------
function changecolor(h, e, progpatch) %#ok<INUSL>
% Change the color of the progress bar patch
% Prevent color from being too dark or too light
colormin = 1.5;
colormax = 2.8;
thiscolor = rand(1, 3);
while (sum(thiscolor) < colormin) || (sum(thiscolor) > colormax)
thiscolor = rand(1, 3);
end
set(progpatch, 'FaceColor', thiscolor)
% ------------------------------------------------------------------------------
function timestr = sec2timestr(sec)
% Convert a time measurement from seconds into a human readable string.
% Convert seconds to other units
w = floor(sec/604800); % Weeks
sec = sec - w*604800;
d = floor(sec/86400); % Days
sec = sec - d*86400;
h = floor(sec/3600); % Hours
sec = sec - h*3600;
m = floor(sec/60); % Minutes
sec = sec - m*60;
s = floor(sec); % Seconds
% Create time string
if w > 0
if w > 9
timestr = sprintf('%d week', w);
else
timestr = sprintf('%d week, %d day', w, d);
end
elseif d > 0
if d > 9
timestr = sprintf('%d day', d);
else
timestr = sprintf('%d day, %d hr', d, h);
end
elseif h > 0
if h > 9
timestr = sprintf('%d hr', h);
else
timestr = sprintf('%d hr, %d min', h, m);
end
elseif m > 0
if m > 9
timestr = sprintf('%d min', m);
else
timestr = sprintf('%d min, %d sec', m, s);
end
else
timestr = sprintf('%d sec', s);
end