sync with trunk (r49238)
[reactos.git] / base / setup / usetup / progress.c
1
2 /* INCLUDES *****************************************************************/
3
4 #include "usetup.h"
5
6 #define NDEBUG
7 #include <debug.h>
8
9 /* FUNCTIONS ****************************************************************/
10
11
12 static VOID
13 DrawBorder(PPROGRESSBAR Bar)
14 {
15 COORD coPos;
16 DWORD Written;
17 SHORT i;
18
19 /* draw upper left corner */
20 coPos.X = Bar->Left;
21 coPos.Y = Bar->Top + 1;
22 FillConsoleOutputCharacterA(StdOutput,
23 0xDA, // '+',
24 1,
25 coPos,
26 &Written);
27
28 /* draw upper edge */
29 coPos.X = Bar->Left + 1;
30 coPos.Y = Bar->Top + 1;
31 FillConsoleOutputCharacterA(StdOutput,
32 0xC4, // '-',
33 Bar->Right - Bar->Left - 1,
34 coPos,
35 &Written);
36
37 /* draw upper right corner */
38 coPos.X = Bar->Right;
39 coPos.Y = Bar->Top + 1;
40 FillConsoleOutputCharacterA(StdOutput,
41 0xBF, // '+',
42 1,
43 coPos,
44 &Written);
45
46 /* draw left and right edge */
47 for (i = Bar->Top + 2; i < Bar->Bottom; i++)
48 {
49 coPos.X = Bar->Left;
50 coPos.Y = i;
51 FillConsoleOutputCharacterA(StdOutput,
52 0xB3, // '|',
53 1,
54 coPos,
55 &Written);
56
57 coPos.X = Bar->Right;
58 FillConsoleOutputCharacterA(StdOutput,
59 0xB3, //'|',
60 1,
61 coPos,
62 &Written);
63 }
64
65 /* draw lower left corner */
66 coPos.X = Bar->Left;
67 coPos.Y = Bar->Bottom;
68 FillConsoleOutputCharacterA(StdOutput,
69 0xC0, // '+',
70 1,
71 coPos,
72 &Written);
73
74 /* draw lower edge */
75 coPos.X = Bar->Left + 1;
76 coPos.Y = Bar->Bottom;
77 FillConsoleOutputCharacterA(StdOutput,
78 0xC4, // '-',
79 Bar->Right - Bar->Left - 1,
80 coPos,
81 &Written);
82
83 /* draw lower right corner */
84 coPos.X = Bar->Right;
85 coPos.Y = Bar->Bottom;
86 FillConsoleOutputCharacterA(StdOutput,
87 0xD9, // '+',
88 1,
89 coPos,
90 &Written);
91 }
92
93 static VOID
94 DrawThickBorder(PPROGRESSBAR Bar)
95 {
96 COORD coPos;
97 DWORD Written;
98 SHORT i;
99
100 /* draw upper left corner */
101 coPos.X = Bar->Left;
102 coPos.Y = Bar->Top + 1;
103 FillConsoleOutputCharacterA(StdOutput,
104 0xC9, // '+',
105 1,
106 coPos,
107 &Written);
108
109 /* draw upper edge */
110 coPos.X = Bar->Left + 1;
111 coPos.Y = Bar->Top + 1;
112 FillConsoleOutputCharacterA(StdOutput,
113 0xCD, // '-',
114 Bar->Right - Bar->Left - 1,
115 coPos,
116 &Written);
117
118 /* draw upper right corner */
119 coPos.X = Bar->Right;
120 coPos.Y = Bar->Top + 1;
121 FillConsoleOutputCharacterA(StdOutput,
122 0xBB, // '+',
123 1,
124 coPos,
125 &Written);
126
127 /* draw left and right edge */
128 for (i = Bar->Top + 2; i < Bar->Bottom; i++)
129 {
130 coPos.X = Bar->Left;
131 coPos.Y = i;
132 FillConsoleOutputCharacterA(StdOutput,
133 0xBA, // '|',
134 1,
135 coPos,
136 &Written);
137
138 coPos.X = Bar->Right;
139 FillConsoleOutputCharacterA(StdOutput,
140 0xBA, //'|',
141 1,
142 coPos,
143 &Written);
144 }
145
146 /* draw lower left corner */
147 coPos.X = Bar->Left;
148 coPos.Y = Bar->Bottom;
149 FillConsoleOutputCharacterA(StdOutput,
150 0xC8, // '+',
151 1,
152 coPos,
153 &Written);
154
155 /* draw lower edge */
156 coPos.X = Bar->Left + 1;
157 coPos.Y = Bar->Bottom;
158 FillConsoleOutputCharacterA(StdOutput,
159 0xCD, // '-',
160 Bar->Right - Bar->Left - 1,
161 coPos,
162 &Written);
163
164 /* draw lower right corner */
165 coPos.X = Bar->Right;
166 coPos.Y = Bar->Bottom;
167 FillConsoleOutputCharacterA(StdOutput,
168 0xBC, // '+',
169 1,
170 coPos,
171 &Written);
172 }
173
174 static VOID
175 DrawProgressBar(PPROGRESSBAR Bar)
176 {
177 CHAR TextBuffer[8];
178 COORD coPos;
179 DWORD Written;
180 PROGRESSBAR BarBorder = *Bar;
181
182 /* Print percentage */
183 sprintf(TextBuffer, "%-3lu%%", Bar->Percent);
184
185 coPos.X = Bar->Left + (Bar->Width - 2) / 2;
186 coPos.Y = Bar->Top;
187 WriteConsoleOutputCharacterA(StdOutput,
188 TextBuffer,
189 4,
190 coPos,
191 &Written);
192
193 /* Draw the progress bar border */
194 DrawBorder(Bar);
195
196 /* Write Text Associated with Bar */
197 CONSOLE_SetTextXY(Bar->TextTop, Bar->TextRight, Bar->Text);
198
199 /* Draw the progress bar "border" border */
200 if (Bar->Double)
201 {
202 BarBorder.Top -= 5;
203 BarBorder.Bottom += 2;
204 BarBorder.Right += 5;
205 BarBorder.Left -= 5;
206 DrawThickBorder(&BarBorder);
207 }
208
209 /* Draw the bar */
210 coPos.X = Bar->Left + 1;
211 for (coPos.Y = Bar->Top + 2; coPos.Y <= Bar->Bottom - 1; coPos.Y++)
212 {
213 FillConsoleOutputAttribute(StdOutput,
214 FOREGROUND_YELLOW | BACKGROUND_BLUE,
215 Bar->Width - 2,
216 coPos,
217 &Written);
218
219 FillConsoleOutputCharacterA(StdOutput,
220 ' ',
221 Bar->Width - 2,
222 coPos,
223 &Written);
224 }
225
226 }
227
228
229
230 PPROGRESSBAR
231 CreateProgressBar(SHORT Left,
232 SHORT Top,
233 SHORT Right,
234 SHORT Bottom,
235 SHORT TextTop,
236 SHORT TextRight,
237 IN BOOLEAN DoubleEdge,
238 char* Text)
239 {
240 PPROGRESSBAR Bar;
241
242 Bar = (PPROGRESSBAR)RtlAllocateHeap(ProcessHeap,
243 0,
244 sizeof(PROGRESSBAR));
245 if (Bar == NULL)
246 return(NULL);
247
248 Bar->Left = Left;
249 Bar->Top = Top;
250 Bar->Right = Right;
251 Bar->Bottom = Bottom;
252 Bar->TextTop = TextTop;
253 Bar->TextRight = TextRight;
254 Bar->Double = DoubleEdge;
255 Bar->Text = Text;
256
257 Bar->Width = Bar->Right - Bar->Left + 1;
258
259 Bar->Percent = 0;
260 Bar->Pos = 0;
261
262 Bar->StepCount = 0;
263 Bar->CurrentStep = 0;
264
265 DrawProgressBar(Bar);
266
267 return(Bar);
268 }
269
270
271 VOID
272 DestroyProgressBar(PPROGRESSBAR Bar)
273 {
274 RtlFreeHeap(ProcessHeap,
275 0,
276 Bar);
277 }
278
279 VOID
280 ProgressSetStepCount(PPROGRESSBAR Bar,
281 ULONG StepCount)
282 {
283 Bar->CurrentStep = 0;
284 Bar->StepCount = StepCount;
285
286 DrawProgressBar(Bar);
287 }
288
289
290 VOID
291 ProgressNextStep(PPROGRESSBAR Bar)
292 {
293 CHAR TextBuffer[8];
294 COORD coPos;
295 DWORD Written;
296 ULONG NewPercent;
297 ULONG NewPos;
298
299 if ((Bar->StepCount == 0) ||
300 (Bar->CurrentStep == Bar->StepCount))
301 return;
302
303 Bar->CurrentStep++;
304
305 /* Calculate new percentage */
306 NewPercent = (ULONG)(((100.0 * (float)Bar->CurrentStep) / (float)Bar->StepCount) + 0.5);
307
308 /* Redraw precentage if changed */
309 if (Bar->Percent != NewPercent)
310 {
311 Bar->Percent = NewPercent;
312
313 sprintf(TextBuffer, "%-3lu%%", Bar->Percent);
314
315 coPos.X = Bar->Left + (Bar->Width - 2) / 2;
316 coPos.Y = Bar->Top;
317 WriteConsoleOutputCharacterA(StdOutput,
318 TextBuffer,
319 4,
320 coPos,
321 &Written);
322 }
323
324 /* Calculate bar position */
325 NewPos = (ULONG)((((float)(Bar->Width - 2) * 2.0 * (float)Bar->CurrentStep) / (float)Bar->StepCount) + 0.5);
326
327 /* Redraw bar if changed */
328 if (Bar->Pos != NewPos)
329 {
330 Bar->Pos = NewPos;
331
332 for (coPos.Y = Bar->Top + 2; coPos.Y <= Bar->Bottom - 1; coPos.Y++)
333 {
334 coPos.X = Bar->Left + 1;
335 FillConsoleOutputCharacterA(StdOutput,
336 0xDB,
337 Bar->Pos / 2,
338 coPos,
339 &Written);
340 coPos.X += Bar->Pos/2;
341
342 if (NewPos & 1)
343 {
344 FillConsoleOutputCharacterA(StdOutput,
345 0xDD,
346 1,
347 coPos,
348 &Written);
349 coPos.X++;
350 }
351
352 if (coPos.X <= Bar->Right - 1)
353 {
354 FillConsoleOutputCharacterA(StdOutput,
355 ' ',
356 Bar->Right - coPos.X,
357 coPos,
358 &Written);
359 }
360 }
361 }
362 }
363
364
365 VOID
366 ProgressSetStep (PPROGRESSBAR Bar,
367 ULONG Step)
368 {
369 CHAR TextBuffer[8];
370 COORD coPos;
371 DWORD Written;
372 ULONG NewPercent;
373 ULONG NewPos;
374
375 if (Step > Bar->StepCount)
376 return;
377
378 Bar->CurrentStep = Step;
379
380 /* Calculate new percentage */
381 NewPercent = (ULONG)(((100.0 * (float)Bar->CurrentStep) / (float)Bar->StepCount) + 0.5);
382
383 /* Redraw precentage if changed */
384 if (Bar->Percent != NewPercent)
385 {
386 Bar->Percent = NewPercent;
387
388 sprintf(TextBuffer, "%-3lu%%", Bar->Percent);
389
390 coPos.X = Bar->Left + (Bar->Width - 2) / 2;
391 coPos.Y = Bar->Top;
392 WriteConsoleOutputCharacterA(StdOutput,
393 TextBuffer,
394 4,
395 coPos,
396 &Written);
397 }
398
399 /* Calculate bar position */
400 NewPos = (ULONG)((((float)(Bar->Width - 2) * 2.0 * (float)Bar->CurrentStep) / (float)Bar->StepCount) + 0.5);
401
402 /* Redraw bar if changed */
403 if (Bar->Pos != NewPos)
404 {
405 Bar->Pos = NewPos;
406
407 for (coPos.Y = Bar->Top + 2; coPos.Y <= Bar->Bottom - 1; coPos.Y++)
408 {
409 coPos.X = Bar->Left + 1;
410 FillConsoleOutputCharacterA(StdOutput,
411 0xDB,
412 Bar->Pos / 2,
413 coPos,
414 &Written);
415 coPos.X += Bar->Pos/2;
416
417 if (NewPos & 1)
418 {
419 FillConsoleOutputCharacterA(StdOutput,
420 0xDD,
421 1,
422 coPos,
423 &Written);
424 coPos.X++;
425 }
426
427 if (coPos.X <= Bar->Right - 1)
428 {
429 FillConsoleOutputCharacterA(StdOutput,
430 ' ',
431 Bar->Right - coPos.X,
432 coPos,
433 &Written);
434 }
435 }
436 }
437 }
438
439 /* EOF */