Synchronize with trunk revision 59636 (just before Alex's CreateProcess revamp).
[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 ProgressSetStep(Bar, Bar->CurrentStep + 1);
294 }
295
296
297 VOID
298 ProgressSetStep (PPROGRESSBAR Bar,
299 ULONG Step)
300 {
301 CHAR TextBuffer[8];
302 COORD coPos;
303 DWORD Written;
304 ULONG NewPercent;
305 ULONG NewPos;
306
307 if (Step > Bar->StepCount)
308 return;
309
310 Bar->CurrentStep = Step;
311
312 /* Calculate new percentage */
313 NewPercent = (ULONG)(((100.0 * (float)Bar->CurrentStep) / (float)Bar->StepCount) + 0.5);
314
315 /* Redraw precentage if changed */
316 if (Bar->Percent != NewPercent)
317 {
318 Bar->Percent = NewPercent;
319
320 sprintf(TextBuffer, "%-3lu%%", Bar->Percent);
321
322 coPos.X = Bar->Left + (Bar->Width - 2) / 2;
323 coPos.Y = Bar->Top;
324 WriteConsoleOutputCharacterA(StdOutput,
325 TextBuffer,
326 4,
327 coPos,
328 &Written);
329 }
330
331 /* Calculate bar position */
332 NewPos = (ULONG)((((float)(Bar->Width - 2) * 2.0 * (float)Bar->CurrentStep) / (float)Bar->StepCount) + 0.5);
333
334 /* Redraw bar if changed */
335 if (Bar->Pos != NewPos)
336 {
337 Bar->Pos = NewPos;
338
339 for (coPos.Y = Bar->Top + 2; coPos.Y <= Bar->Bottom - 1; coPos.Y++)
340 {
341 coPos.X = Bar->Left + 1;
342 FillConsoleOutputCharacterA(StdOutput,
343 0xDB,
344 Bar->Pos / 2,
345 coPos,
346 &Written);
347 coPos.X += Bar->Pos/2;
348
349 if (NewPos & 1)
350 {
351 FillConsoleOutputCharacterA(StdOutput,
352 0xDD,
353 1,
354 coPos,
355 &Written);
356 coPos.X++;
357 }
358
359 if (coPos.X <= Bar->Right - 1)
360 {
361 FillConsoleOutputCharacterA(StdOutput,
362 ' ',
363 Bar->Right - coPos.X,
364 coPos,
365 &Written);
366 }
367 }
368 }
369 }
370
371 /* EOF */