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