[USETUP] Implement CreateProgressBarEx() (#791)
[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 Bar->ProgressColour,
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 CreateProgressBarEx(
238 SHORT Left,
239 SHORT Top,
240 SHORT Right,
241 SHORT Bottom,
242 SHORT TextTop,
243 SHORT TextRight,
244 IN BOOLEAN DoubleEdge,
245 SHORT ProgressColour,
246 CHAR *Text)
247 {
248 PPROGRESSBAR Bar;
249
250 Bar = (PPROGRESSBAR)RtlAllocateHeap(ProcessHeap,
251 0,
252 sizeof(PROGRESSBAR));
253 if (Bar == NULL)
254 return NULL;
255
256 Bar->Left = Left;
257 Bar->Top = Top;
258 Bar->Right = Right;
259 Bar->Bottom = Bottom;
260 Bar->TextTop = TextTop;
261 Bar->TextRight = TextRight;
262 Bar->Double = DoubleEdge;
263 Bar->ProgressColour = ProgressColour;
264 Bar->Text = Text;
265
266 Bar->Width = Bar->Right - Bar->Left + 1;
267
268 Bar->Percent = 0;
269 Bar->Pos = 0;
270
271 Bar->StepCount = 0;
272 Bar->CurrentStep = 0;
273
274 DrawProgressBar(Bar);
275
276 return Bar;
277 }
278
279 PPROGRESSBAR
280 CreateProgressBar(
281 SHORT Left,
282 SHORT Top,
283 SHORT Right,
284 SHORT Bottom,
285 SHORT TextTop,
286 SHORT TextRight,
287 IN BOOLEAN DoubleEdge,
288 CHAR *Text)
289 {
290
291 /* Call the Ex variant of the function */
292 return CreateProgressBarEx(Left, Top, Right, Bottom,
293 TextTop, TextRight,
294 DoubleEdge,
295 FOREGROUND_YELLOW | BACKGROUND_BLUE,
296 Text);
297 }
298
299 VOID
300 DestroyProgressBar(
301 PPROGRESSBAR Bar)
302 {
303 RtlFreeHeap(ProcessHeap, 0, Bar);
304 }
305
306
307 VOID
308 ProgressSetStepCount(
309 PPROGRESSBAR Bar,
310 ULONG StepCount)
311 {
312 Bar->CurrentStep = 0;
313 Bar->StepCount = StepCount;
314
315 DrawProgressBar(Bar);
316 }
317
318
319 VOID
320 ProgressNextStep(
321 PPROGRESSBAR Bar)
322 {
323 ProgressSetStep(Bar, Bar->CurrentStep + 1);
324 }
325
326
327 VOID
328 ProgressSetStep(
329 PPROGRESSBAR Bar,
330 ULONG Step)
331 {
332 CHAR TextBuffer[8];
333 COORD coPos;
334 DWORD Written;
335 ULONG NewPercent;
336 ULONG NewPos;
337
338 if (Step > Bar->StepCount)
339 return;
340
341 Bar->CurrentStep = Step;
342
343 /* Calculate new percentage */
344 NewPercent = (ULONG)(((100.0 * (float)Bar->CurrentStep) / (float)Bar->StepCount) + 0.5);
345
346 /* Redraw percentage if changed */
347 if (Bar->Percent != NewPercent)
348 {
349 Bar->Percent = NewPercent;
350
351 sprintf(TextBuffer, "%-3lu%%", Bar->Percent);
352
353 coPos.X = Bar->Left + (Bar->Width - 2) / 2;
354 coPos.Y = Bar->Top;
355 WriteConsoleOutputCharacterA(StdOutput,
356 TextBuffer,
357 4,
358 coPos,
359 &Written);
360 }
361
362 /* Calculate bar position */
363 NewPos = (ULONG)((((float)(Bar->Width - 2) * 2.0 * (float)Bar->CurrentStep) / (float)Bar->StepCount) + 0.5);
364
365 /* Redraw bar if changed */
366 if (Bar->Pos != NewPos)
367 {
368 Bar->Pos = NewPos;
369
370 for (coPos.Y = Bar->Top + 2; coPos.Y <= Bar->Bottom - 1; coPos.Y++)
371 {
372 coPos.X = Bar->Left + 1;
373 FillConsoleOutputCharacterA(StdOutput,
374 0xDB,
375 Bar->Pos / 2,
376 coPos,
377 &Written);
378 coPos.X += Bar->Pos/2;
379
380 if (NewPos & 1)
381 {
382 FillConsoleOutputCharacterA(StdOutput,
383 0xDD,
384 1,
385 coPos,
386 &Written);
387 coPos.X++;
388 }
389
390 if (coPos.X <= Bar->Right - 1)
391 {
392 FillConsoleOutputCharacterA(StdOutput,
393 ' ',
394 Bar->Right - coPos.X,
395 coPos,
396 &Written);
397 }
398 }
399 }
400 }
401
402 /* EOF */