ReactOS 0.4.16-dev-329-g9223134
genlist.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19/*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: base/setup/usetup/genlist.c
23 * PURPOSE: Generic list functions
24 * PROGRAMMER: Christoph von Wittich <christoph at reactos.org>
25 */
26
27/* INCLUDES *****************************************************************/
28
29#include "usetup.h"
30
31#define NDEBUG
32#include <debug.h>
33
34/* FUNCTIONS ****************************************************************/
35
36VOID
38 IN OUT PGENERIC_LIST_UI ListUi,
40 IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc)
41{
42 ListUi->List = List;
43 ListUi->FirstShown = NULL;
44 ListUi->LastShown = NULL;
45 ListUi->BackupEntry = NULL;
46
47 ListUi->GetEntryDescriptionProc = GetEntryDescriptionProc;
48
49 ListUi->Left = 0;
50 ListUi->Top = 0;
51 ListUi->Right = 0;
52 ListUi->Bottom = 0;
53 ListUi->Redraw = TRUE;
54
55 ListUi->CurrentItemText[0] = ANSI_NULL;
56
57 /* SaveGenericListUiState(ListUi); */
58 ListUi->BackupEntry = ListUi->List->CurrentEntry;
59}
60
61VOID
63 IN PGENERIC_LIST_UI ListUi)
64{
65 ListUi->List->CurrentEntry = ListUi->BackupEntry;
66}
67
68static
69VOID
71 IN PGENERIC_LIST_UI ListUi)
72{
73 COORD coPos;
74 DWORD Written;
75 SHORT i;
76
77 /* Draw upper left corner */
78 coPos.X = ListUi->Left;
79 coPos.Y = ListUi->Top;
81 CharUpperLeftCorner, // '+',
82 1,
83 coPos,
84 &Written);
85
86 /* Draw upper edge */
87 coPos.X = ListUi->Left + 1;
88 coPos.Y = ListUi->Top;
90 CharHorizontalLine, // '-',
91 ListUi->Right - ListUi->Left - 1,
92 coPos,
93 &Written);
94
95 /* Draw upper right corner */
96 coPos.X = ListUi->Right;
97 coPos.Y = ListUi->Top;
100 1,
101 coPos,
102 &Written);
103
104 /* Draw left and right edge */
105 for (i = ListUi->Top + 1; i < ListUi->Bottom; i++)
106 {
107 coPos.X = ListUi->Left;
108 coPos.Y = i;
110 CharVerticalLine, // '|',
111 1,
112 coPos,
113 &Written);
114
115 coPos.X = ListUi->Right;
117 CharVerticalLine, //'|',
118 1,
119 coPos,
120 &Written);
121 }
122
123 /* Draw lower left corner */
124 coPos.X = ListUi->Left;
125 coPos.Y = ListUi->Bottom;
127 CharLowerLeftCorner, // '+',
128 1,
129 coPos,
130 &Written);
131
132 /* Draw lower edge */
133 coPos.X = ListUi->Left + 1;
134 coPos.Y = ListUi->Bottom;
136 CharHorizontalLine, // '-',
137 ListUi->Right - ListUi->Left - 1,
138 coPos,
139 &Written);
140
141 /* Draw lower right corner */
142 coPos.X = ListUi->Right;
143 coPos.Y = ListUi->Bottom;
145 CharLowerRightCorner, // '+',
146 1,
147 coPos,
148 &Written);
149}
150
151static
152VOID
154 IN PGENERIC_LIST_UI ListUi)
155{
156 PGENERIC_LIST List = ListUi->List;
157 PGENERIC_LIST_ENTRY ListEntry;
159 COORD coPos;
160 DWORD Written;
162
163 coPos.X = ListUi->Left + 1;
164 coPos.Y = ListUi->Top + 1;
165 Width = ListUi->Right - ListUi->Left - 1;
166
167 Entry = ListUi->FirstShown;
168 while (Entry != &List->ListHead)
169 {
171
172 if (coPos.Y == ListUi->Bottom)
173 break;
174 ListUi->LastShown = Entry;
175
176 ListUi->CurrentItemText[0] = ANSI_NULL;
177 if (ListUi->GetEntryDescriptionProc)
178 {
179 ListUi->GetEntryDescriptionProc(ListEntry,
180 ListUi->CurrentItemText,
181 ARRAYSIZE(ListUi->CurrentItemText));
182 }
183
185 (List->CurrentEntry == ListEntry) ?
188 Width,
189 coPos,
190 &Written);
191
193 ' ',
194 Width,
195 coPos,
196 &Written);
197
198 coPos.X++;
200 ListUi->CurrentItemText,
201 min(strlen(ListUi->CurrentItemText), (SIZE_T)Width - 2),
202 coPos,
203 &Written);
204 coPos.X--;
205
206 coPos.Y++;
207 Entry = Entry->Flink;
208 }
209
210 while (coPos.Y < ListUi->Bottom)
211 {
214 Width,
215 coPos,
216 &Written);
217
219 ' ',
220 Width,
221 coPos,
222 &Written);
223 coPos.Y++;
224 }
225}
226
227static
228VOID
230 IN PGENERIC_LIST_UI ListUi)
231{
232 PGENERIC_LIST List = ListUi->List;
233 COORD coPos;
234 DWORD Written;
235
236 coPos.X = ListUi->Right + 1;
237 coPos.Y = ListUi->Top;
238
239 if (ListUi->FirstShown != List->ListHead.Flink)
240 {
243 1,
244 coPos,
245 &Written);
246 }
247 else
248 {
250 ' ',
251 1,
252 coPos,
253 &Written);
254 }
255
256 coPos.Y = ListUi->Bottom;
257 if (ListUi->LastShown != List->ListHead.Blink)
258 {
261 1,
262 coPos,
263 &Written);
264 }
265 else
266 {
268 ' ',
269 1,
270 coPos,
271 &Written);
272 }
273}
274
275static
276VOID
278 IN PGENERIC_LIST_UI ListUi)
279{
280 PGENERIC_LIST List = ListUi->List;
282 ULONG MaxVisibleItems, ItemCount, i;
283
284 if ((ListUi->Top == 0 && ListUi->Bottom == 0) ||
285 IsListEmpty(&List->ListHead) ||
286 List->CurrentEntry == NULL)
287 {
288 return;
289 }
290
291 MaxVisibleItems = (ULONG)(ListUi->Bottom - ListUi->Top - 1);
292
293/*****************************************
294 ItemCount = 0;
295 Entry = List->ListHead.Flink;
296 while (Entry != &List->ListHead)
297 {
298 ItemCount++;
299 Entry = Entry->Flink;
300 }
301*****************************************/
302 ItemCount = List->NumOfEntries; // GetNumberOfListEntries(List);
303
304 if (ItemCount > MaxVisibleItems)
305 {
306 Entry = &List->CurrentEntry->Entry;
307 for (i = 0; i < MaxVisibleItems / 2; i++)
308 {
309 if (Entry->Blink != &List->ListHead)
310 Entry = Entry->Blink;
311 }
312
313 ListUi->FirstShown = Entry;
314
315 for (i = 0; i < MaxVisibleItems; i++)
316 {
317 if (Entry->Flink != &List->ListHead)
318 Entry = Entry->Flink;
319 }
320
321 ListUi->LastShown = Entry;
322 }
323}
324
325VOID
327 IN PGENERIC_LIST_UI ListUi,
328 IN SHORT Left,
329 IN SHORT Top,
330 IN SHORT Right,
332{
333 PGENERIC_LIST List = ListUi->List;
334
335 ListUi->FirstShown = List->ListHead.Flink;
336 ListUi->Left = Left;
337 ListUi->Top = Top;
338 ListUi->Right = Right;
339 ListUi->Bottom = Bottom;
340
341 DrawListFrame(ListUi);
342
343 if (IsListEmpty(&List->ListHead))
344 return;
345
346 CenterCurrentListItem(ListUi);
347
348 DrawListEntries(ListUi);
350}
351
352VOID
355 IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc,
356 IN SHORT Left,
357 IN SHORT Top)
358{
359 CHAR CurrentItemText[256];
360
361 if (GetEntryDescriptionProc &&
363 {
364 GetEntryDescriptionProc(GetCurrentListEntry(List),
365 CurrentItemText,
366 ARRAYSIZE(CurrentItemText));
367 CONSOLE_SetTextXY(Left, Top, CurrentItemText);
368 }
369 else
370 {
371 CONSOLE_SetTextXY(Left, Top, "");
372 }
373}
374
375VOID
377 IN PGENERIC_LIST_UI ListUi)
378{
379 PGENERIC_LIST List = ListUi->List;
381
382 if (List->CurrentEntry == NULL)
383 return;
384
385 if (List->CurrentEntry->Entry.Flink != &List->ListHead)
386 {
387 Entry = List->CurrentEntry->Entry.Flink;
388 if (ListUi->LastShown == &List->CurrentEntry->Entry)
389 {
390 ListUi->FirstShown = ListUi->FirstShown->Flink;
391 ListUi->LastShown = ListUi->LastShown->Flink;
392 }
394
395 if (ListUi->Redraw)
396 {
397 DrawListEntries(ListUi);
399 }
400 }
401}
402
403VOID
405 IN PGENERIC_LIST_UI ListUi)
406{
407 PGENERIC_LIST List = ListUi->List;
409
410 if (List->CurrentEntry == NULL)
411 return;
412
413 if (List->CurrentEntry->Entry.Blink != &List->ListHead)
414 {
415 Entry = List->CurrentEntry->Entry.Blink;
416 if (ListUi->FirstShown == &List->CurrentEntry->Entry)
417 {
418 ListUi->FirstShown = ListUi->FirstShown->Blink;
419 ListUi->LastShown = ListUi->LastShown->Blink;
420 }
422
423 if (ListUi->Redraw)
424 {
425 DrawListEntries(ListUi);
427 }
428 }
429}
430
431VOID
433 IN PGENERIC_LIST_UI ListUi)
434{
435 SHORT i;
436
437 /* Suspend auto-redraw */
438 ListUi->Redraw = FALSE;
439
440 for (i = ListUi->Top + 1; i < ListUi->Bottom - 1; i++)
441 {
442 ScrollDownGenericList(ListUi);
443 }
444
445 /* Update user interface */
446 DrawListEntries(ListUi);
448
449 /* Re enable auto-redraw */
450 ListUi->Redraw = TRUE;
451}
452
453VOID
455 IN PGENERIC_LIST_UI ListUi)
456{
457 SHORT i;
458
459 /* Suspend auto-redraw */
460 ListUi->Redraw = FALSE;
461
462 for (i = ListUi->Bottom - 1; i > ListUi->Top + 1; i--)
463 {
464 ScrollUpGenericList(ListUi);
465 }
466
467 /* Update user interface */
468 DrawListEntries(ListUi);
470
471 /* Re enable auto-redraw */
472 ListUi->Redraw = TRUE;
473}
474
475VOID
477 IN PGENERIC_LIST_UI ListUi,
478 IN ULONG uIndex)
479{
480 PGENERIC_LIST List = ListUi->List;
482 ULONG uCount = 0;
483
484 if (List->CurrentEntry == NULL || uIndex == 0)
485 return;
486
487 do
488 {
489 if (List->CurrentEntry->Entry.Flink != &List->ListHead)
490 {
491 Entry = List->CurrentEntry->Entry.Flink;
492 if (ListUi->LastShown == &List->CurrentEntry->Entry)
493 {
494 ListUi->FirstShown = ListUi->FirstShown->Flink;
495 ListUi->LastShown = ListUi->LastShown->Flink;
496 }
498 }
499 uCount++;
500 }
501 while (uIndex != uCount);
502
503 if (ListUi->Redraw)
504 {
505 DrawListEntries(ListUi);
507 }
508}
509
510VOID
512 IN PGENERIC_LIST_UI ListUi)
513{
514 if (ListUi->List->CurrentEntry == NULL)
515 return;
516
517 if (ListUi->Redraw)
518 {
519 DrawListEntries(ListUi);
521 }
522}
523
524VOID
526 IN PGENERIC_LIST_UI ListUi,
527 IN CHAR AsciiChar)
528{
529 PGENERIC_LIST List = ListUi->List;
530 PGENERIC_LIST_ENTRY ListEntry;
531 PGENERIC_LIST_ENTRY OldListEntry;
533
534 ListEntry = List->CurrentEntry;
535 OldListEntry = List->CurrentEntry;
536
537 ListUi->Redraw = FALSE;
538
539 ListUi->CurrentItemText[0] = ANSI_NULL;
540 if (ListUi->GetEntryDescriptionProc)
541 {
542 ListUi->GetEntryDescriptionProc(ListEntry,
543 ListUi->CurrentItemText,
544 ARRAYSIZE(ListUi->CurrentItemText));
545 }
546
547 if ((strlen(ListUi->CurrentItemText) > 0) && (tolower(ListUi->CurrentItemText[0]) == AsciiChar) &&
548 (List->CurrentEntry->Entry.Flink != &List->ListHead))
549 {
550 ScrollDownGenericList(ListUi);
551 ListEntry = List->CurrentEntry;
552
553 ListUi->CurrentItemText[0] = ANSI_NULL;
554 if (ListUi->GetEntryDescriptionProc)
555 {
556 ListUi->GetEntryDescriptionProc(ListEntry,
557 ListUi->CurrentItemText,
558 ARRAYSIZE(ListUi->CurrentItemText));
559 }
560
561 if ((strlen(ListUi->CurrentItemText) > 0) && (tolower(ListUi->CurrentItemText[0]) == AsciiChar))
562 goto End;
563 }
564
565 while (List->CurrentEntry->Entry.Blink != &List->ListHead)
566 ScrollUpGenericList(ListUi);
567
568 ListEntry = List->CurrentEntry;
569
570 for (;;)
571 {
572 ListUi->CurrentItemText[0] = ANSI_NULL;
573 if (ListUi->GetEntryDescriptionProc)
574 {
575 ListUi->GetEntryDescriptionProc(ListEntry,
576 ListUi->CurrentItemText,
577 ARRAYSIZE(ListUi->CurrentItemText));
578 }
579
580 if ((strlen(ListUi->CurrentItemText) > 0) && (tolower(ListUi->CurrentItemText[0]) == AsciiChar))
581 {
582 Flag = TRUE;
583 break;
584 }
585
586 if (List->CurrentEntry->Entry.Flink == &List->ListHead)
587 break;
588
589 ScrollDownGenericList(ListUi);
590 ListEntry = List->CurrentEntry;
591 }
592
593 if (!Flag)
594 {
595 while (List->CurrentEntry->Entry.Blink != &List->ListHead)
596 {
597 if (List->CurrentEntry != OldListEntry)
598 ScrollUpGenericList(ListUi);
599 else
600 break;
601 }
602 }
603
604End:
605 DrawListEntries(ListUi);
607
608 ListUi->Redraw = TRUE;
609}
610
611/* EOF */
unsigned char BOOLEAN
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int tolower(int c)
Definition: utclib.c:902
VOID(NTAPI * PGET_ENTRY_DESCRIPTION)(IN PGENERIC_LIST_ENTRY Entry, OUT PWSTR Buffer, IN SIZE_T cchBufferSize)
Definition: reactos.c:511
BOOL WINAPI WriteConsoleOutputCharacterA(HANDLE hConsoleOutput, IN LPCSTR lpCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: console.c:407
BOOL WINAPI FillConsoleOutputCharacterA(IN HANDLE hConsoleOutput, IN CHAR cCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: console.c:560
BOOL WINAPI FillConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN WORD wAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: console.c:525
static LPHIST_ENTRY Bottom
Definition: history.c:54
static LPHIST_ENTRY Top
Definition: history.c:53
#define BACKGROUND_BLUE
Definition: blue.h:65
#define FOREGROUND_BLUE
Definition: blue.h:61
VOID CONSOLE_SetTextXY(IN SHORT x, IN SHORT y, IN LPCSTR Text)
Definition: consup.c:320
HANDLE StdOutput
Definition: consup.c:37
#define FOREGROUND_WHITE
Definition: consup.h:29
#define BACKGROUND_WHITE
Definition: consup.h:31
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG NTAPI GetNumberOfListEntries(IN PGENERIC_LIST List)
Definition: genlist.c:149
PGENERIC_LIST_ENTRY NTAPI GetCurrentListEntry(IN PGENERIC_LIST List)
Definition: genlist.c:102
#define min(a, b)
Definition: monoChain.cc:55
#define ANSI_NULL
short SHORT
Definition: pedump.c:59
unsigned short USHORT
Definition: pedump.c:61
base of all file and directory entries
Definition: entries.h:83
Entry(ENTRY_TYPE etype)
Definition: entries.cpp:35
Definition: xml2sdb.h:80
Definition: bl.h:1338
ULONG Y
Definition: bl.h:1340
ULONG X
Definition: bl.h:1339
Definition: genlist.h:11
LIST_ENTRY ListHead
Definition: genlist.h:20
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:89
VOID RedrawGenericList(IN PGENERIC_LIST_UI ListUi)
Definition: genlist.c:511
VOID InitGenericListUi(IN OUT PGENERIC_LIST_UI ListUi, IN PGENERIC_LIST List, IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc)
Definition: genlist.c:37
VOID ScrollPageUpGenericList(IN PGENERIC_LIST_UI ListUi)
Definition: genlist.c:454
static VOID DrawListFrame(IN PGENERIC_LIST_UI ListUi)
Definition: genlist.c:70
VOID ScrollToPositionGenericList(IN PGENERIC_LIST_UI ListUi, IN ULONG uIndex)
Definition: genlist.c:476
VOID RestoreGenericListUiState(IN PGENERIC_LIST_UI ListUi)
Definition: genlist.c:62
VOID GenericListKeyPress(IN PGENERIC_LIST_UI ListUi, IN CHAR AsciiChar)
Definition: genlist.c:525
VOID DrawGenericList(IN PGENERIC_LIST_UI ListUi, IN SHORT Left, IN SHORT Top, IN SHORT Right, IN SHORT Bottom)
Definition: genlist.c:326
static VOID DrawScrollBarGenericList(IN PGENERIC_LIST_UI ListUi)
Definition: genlist.c:229
static VOID CenterCurrentListItem(IN PGENERIC_LIST_UI ListUi)
Definition: genlist.c:277
VOID ScrollUpGenericList(IN PGENERIC_LIST_UI ListUi)
Definition: genlist.c:404
static VOID DrawListEntries(IN PGENERIC_LIST_UI ListUi)
Definition: genlist.c:153
VOID ScrollDownGenericList(IN PGENERIC_LIST_UI ListUi)
Definition: genlist.c:376
VOID ScrollPageDownGenericList(IN PGENERIC_LIST_UI ListUi)
Definition: genlist.c:432
VOID DrawGenericListCurrentItem(IN PGENERIC_LIST List, IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc, IN SHORT Left, IN SHORT Top)
Definition: genlist.c:353
CHAR CharHorizontalLine
Definition: mui.c:39
CHAR CharUpperRightCorner
Definition: mui.c:42
CHAR CharDownArrow
Definition: mui.c:38
CHAR CharLowerRightCorner
Definition: mui.c:44
CHAR CharUpperLeftCorner
Definition: mui.c:41
CHAR CharVerticalLine
Definition: mui.c:40
CHAR CharLowerLeftCorner
Definition: mui.c:43
CHAR CharUpArrow
Definition: mui.c:37
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
char CHAR
Definition: xmlstorage.h:175