3 * Copyright (C) 2004 ReactOS Team
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.
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.
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.
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>
27 /* INCLUDES *****************************************************************/
34 /* FUNCTIONS ****************************************************************/
38 IN OUT PGENERIC_LIST_UI ListUi
,
39 IN PGENERIC_LIST List
,
40 IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc
)
43 ListUi
->FirstShown
= NULL
;
44 ListUi
->LastShown
= NULL
;
45 ListUi
->BackupEntry
= NULL
;
47 ListUi
->GetEntryDescriptionProc
= GetEntryDescriptionProc
;
53 ListUi
->Redraw
= TRUE
;
55 ListUi
->CurrentItemText
[0] = ANSI_NULL
;
57 /* SaveGenericListUiState(ListUi); */
58 ListUi
->BackupEntry
= ListUi
->List
->CurrentEntry
;
62 RestoreGenericListUiState(
63 IN PGENERIC_LIST_UI ListUi
)
65 ListUi
->List
->CurrentEntry
= ListUi
->BackupEntry
;
71 IN PGENERIC_LIST_UI ListUi
)
77 /* Draw upper left corner */
78 coPos
.X
= ListUi
->Left
;
79 coPos
.Y
= ListUi
->Top
;
80 FillConsoleOutputCharacterA(StdOutput
,
87 coPos
.X
= ListUi
->Left
+ 1;
88 coPos
.Y
= ListUi
->Top
;
89 FillConsoleOutputCharacterA(StdOutput
,
91 ListUi
->Right
- ListUi
->Left
- 1,
95 /* Draw upper right corner */
96 coPos
.X
= ListUi
->Right
;
97 coPos
.Y
= ListUi
->Top
;
98 FillConsoleOutputCharacterA(StdOutput
,
104 /* Draw left and right edge */
105 for (i
= ListUi
->Top
+ 1; i
< ListUi
->Bottom
; i
++)
107 coPos
.X
= ListUi
->Left
;
109 FillConsoleOutputCharacterA(StdOutput
,
115 coPos
.X
= ListUi
->Right
;
116 FillConsoleOutputCharacterA(StdOutput
,
123 /* Draw lower left corner */
124 coPos
.X
= ListUi
->Left
;
125 coPos
.Y
= ListUi
->Bottom
;
126 FillConsoleOutputCharacterA(StdOutput
,
132 /* Draw lower edge */
133 coPos
.X
= ListUi
->Left
+ 1;
134 coPos
.Y
= ListUi
->Bottom
;
135 FillConsoleOutputCharacterA(StdOutput
,
137 ListUi
->Right
- ListUi
->Left
- 1,
141 /* Draw lower right corner */
142 coPos
.X
= ListUi
->Right
;
143 coPos
.Y
= ListUi
->Bottom
;
144 FillConsoleOutputCharacterA(StdOutput
,
154 IN PGENERIC_LIST_UI ListUi
)
156 PGENERIC_LIST List
= ListUi
->List
;
157 PGENERIC_LIST_ENTRY ListEntry
;
163 coPos
.X
= ListUi
->Left
+ 1;
164 coPos
.Y
= ListUi
->Top
+ 1;
165 Width
= ListUi
->Right
- ListUi
->Left
- 1;
167 Entry
= ListUi
->FirstShown
;
168 while (Entry
!= &List
->ListHead
)
170 ListEntry
= CONTAINING_RECORD(Entry
, GENERIC_LIST_ENTRY
, Entry
);
172 if (coPos
.Y
== ListUi
->Bottom
)
174 ListUi
->LastShown
= Entry
;
176 ListUi
->CurrentItemText
[0] = ANSI_NULL
;
177 if (ListUi
->GetEntryDescriptionProc
)
179 ListUi
->GetEntryDescriptionProc(ListEntry
,
180 ListUi
->CurrentItemText
,
181 ARRAYSIZE(ListUi
->CurrentItemText
));
184 FillConsoleOutputAttribute(StdOutput
,
185 (List
->CurrentEntry
== ListEntry
) ?
186 FOREGROUND_BLUE
| BACKGROUND_WHITE
:
187 FOREGROUND_WHITE
| BACKGROUND_BLUE
,
192 FillConsoleOutputCharacterA(StdOutput
,
199 WriteConsoleOutputCharacterA(StdOutput
,
200 ListUi
->CurrentItemText
,
201 min(strlen(ListUi
->CurrentItemText
), (SIZE_T
)Width
- 2),
207 Entry
= Entry
->Flink
;
210 while (coPos
.Y
< ListUi
->Bottom
)
212 FillConsoleOutputAttribute(StdOutput
,
213 FOREGROUND_WHITE
| BACKGROUND_BLUE
,
218 FillConsoleOutputCharacterA(StdOutput
,
229 DrawScrollBarGenericList(
230 IN PGENERIC_LIST_UI ListUi
)
232 PGENERIC_LIST List
= ListUi
->List
;
236 coPos
.X
= ListUi
->Right
+ 1;
237 coPos
.Y
= ListUi
->Top
;
239 if (ListUi
->FirstShown
!= List
->ListHead
.Flink
)
241 FillConsoleOutputCharacterA(StdOutput
,
249 FillConsoleOutputCharacterA(StdOutput
,
256 coPos
.Y
= ListUi
->Bottom
;
257 if (ListUi
->LastShown
!= List
->ListHead
.Blink
)
259 FillConsoleOutputCharacterA(StdOutput
,
267 FillConsoleOutputCharacterA(StdOutput
,
277 CenterCurrentListItem(
278 IN PGENERIC_LIST_UI ListUi
)
280 PGENERIC_LIST List
= ListUi
->List
;
282 ULONG MaxVisibleItems
, ItemCount
, i
;
284 if ((ListUi
->Top
== 0 && ListUi
->Bottom
== 0) ||
285 IsListEmpty(&List
->ListHead
) ||
286 List
->CurrentEntry
== NULL
)
291 MaxVisibleItems
= (ULONG
)(ListUi
->Bottom
- ListUi
->Top
- 1);
293 /*****************************************
295 Entry = List->ListHead.Flink;
296 while (Entry != &List->ListHead)
299 Entry = Entry->Flink;
301 *****************************************/
302 ItemCount
= List
->NumOfEntries
; // GetNumberOfListEntries(List);
304 if (ItemCount
> MaxVisibleItems
)
306 Entry
= &List
->CurrentEntry
->Entry
;
307 for (i
= 0; i
< MaxVisibleItems
/ 2; i
++)
309 if (Entry
->Blink
!= &List
->ListHead
)
310 Entry
= Entry
->Blink
;
313 ListUi
->FirstShown
= Entry
;
315 for (i
= 0; i
< MaxVisibleItems
; i
++)
317 if (Entry
->Flink
!= &List
->ListHead
)
318 Entry
= Entry
->Flink
;
321 ListUi
->LastShown
= Entry
;
327 IN PGENERIC_LIST_UI ListUi
,
333 PGENERIC_LIST List
= ListUi
->List
;
335 ListUi
->FirstShown
= List
->ListHead
.Flink
;
338 ListUi
->Right
= Right
;
339 ListUi
->Bottom
= Bottom
;
341 DrawListFrame(ListUi
);
343 if (IsListEmpty(&List
->ListHead
))
346 CenterCurrentListItem(ListUi
);
348 DrawListEntries(ListUi
);
349 DrawScrollBarGenericList(ListUi
);
353 DrawGenericListCurrentItem(
354 IN PGENERIC_LIST List
,
355 IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc
,
359 CHAR CurrentItemText
[256];
361 if (GetEntryDescriptionProc
&&
362 GetNumberOfListEntries(List
) > 0)
364 GetEntryDescriptionProc(GetCurrentListEntry(List
),
366 ARRAYSIZE(CurrentItemText
));
367 CONSOLE_SetTextXY(Left
, Top
, CurrentItemText
);
371 CONSOLE_SetTextXY(Left
, Top
, "");
376 ScrollDownGenericList(
377 IN PGENERIC_LIST_UI ListUi
)
379 PGENERIC_LIST List
= ListUi
->List
;
382 if (List
->CurrentEntry
== NULL
)
385 if (List
->CurrentEntry
->Entry
.Flink
!= &List
->ListHead
)
387 Entry
= List
->CurrentEntry
->Entry
.Flink
;
388 if (ListUi
->LastShown
== &List
->CurrentEntry
->Entry
)
390 ListUi
->FirstShown
= ListUi
->FirstShown
->Flink
;
391 ListUi
->LastShown
= ListUi
->LastShown
->Flink
;
393 List
->CurrentEntry
= CONTAINING_RECORD(Entry
, GENERIC_LIST_ENTRY
, Entry
);
397 DrawListEntries(ListUi
);
398 DrawScrollBarGenericList(ListUi
);
405 IN PGENERIC_LIST_UI ListUi
)
407 PGENERIC_LIST List
= ListUi
->List
;
410 if (List
->CurrentEntry
== NULL
)
413 if (List
->CurrentEntry
->Entry
.Blink
!= &List
->ListHead
)
415 Entry
= List
->CurrentEntry
->Entry
.Blink
;
416 if (ListUi
->FirstShown
== &List
->CurrentEntry
->Entry
)
418 ListUi
->FirstShown
= ListUi
->FirstShown
->Blink
;
419 ListUi
->LastShown
= ListUi
->LastShown
->Blink
;
421 List
->CurrentEntry
= CONTAINING_RECORD(Entry
, GENERIC_LIST_ENTRY
, Entry
);
425 DrawListEntries(ListUi
);
426 DrawScrollBarGenericList(ListUi
);
432 ScrollPageDownGenericList(
433 IN PGENERIC_LIST_UI ListUi
)
437 /* Suspend auto-redraw */
438 ListUi
->Redraw
= FALSE
;
440 for (i
= ListUi
->Top
+ 1; i
< ListUi
->Bottom
- 1; i
++)
442 ScrollDownGenericList(ListUi
);
445 /* Update user interface */
446 DrawListEntries(ListUi
);
447 DrawScrollBarGenericList(ListUi
);
449 /* Re enable auto-redraw */
450 ListUi
->Redraw
= TRUE
;
454 ScrollPageUpGenericList(
455 IN PGENERIC_LIST_UI ListUi
)
459 /* Suspend auto-redraw */
460 ListUi
->Redraw
= FALSE
;
462 for (i
= ListUi
->Bottom
- 1; i
> ListUi
->Top
+ 1; i
--)
464 ScrollUpGenericList(ListUi
);
467 /* Update user interface */
468 DrawListEntries(ListUi
);
469 DrawScrollBarGenericList(ListUi
);
471 /* Re enable auto-redraw */
472 ListUi
->Redraw
= TRUE
;
476 ScrollToPositionGenericList(
477 IN PGENERIC_LIST_UI ListUi
,
480 PGENERIC_LIST List
= ListUi
->List
;
484 if (List
->CurrentEntry
== NULL
|| uIndex
== 0)
489 if (List
->CurrentEntry
->Entry
.Flink
!= &List
->ListHead
)
491 Entry
= List
->CurrentEntry
->Entry
.Flink
;
492 if (ListUi
->LastShown
== &List
->CurrentEntry
->Entry
)
494 ListUi
->FirstShown
= ListUi
->FirstShown
->Flink
;
495 ListUi
->LastShown
= ListUi
->LastShown
->Flink
;
497 List
->CurrentEntry
= CONTAINING_RECORD(Entry
, GENERIC_LIST_ENTRY
, Entry
);
501 while (uIndex
!= uCount
);
505 DrawListEntries(ListUi
);
506 DrawScrollBarGenericList(ListUi
);
512 IN PGENERIC_LIST_UI ListUi
)
514 if (ListUi
->List
->CurrentEntry
== NULL
)
519 DrawListEntries(ListUi
);
520 DrawScrollBarGenericList(ListUi
);
526 IN PGENERIC_LIST_UI ListUi
,
529 PGENERIC_LIST List
= ListUi
->List
;
530 PGENERIC_LIST_ENTRY ListEntry
;
531 PGENERIC_LIST_ENTRY OldListEntry
;
532 BOOLEAN Flag
= FALSE
;
534 ListEntry
= List
->CurrentEntry
;
535 OldListEntry
= List
->CurrentEntry
;
537 ListUi
->Redraw
= FALSE
;
539 ListUi
->CurrentItemText
[0] = ANSI_NULL
;
540 if (ListUi
->GetEntryDescriptionProc
)
542 ListUi
->GetEntryDescriptionProc(ListEntry
,
543 ListUi
->CurrentItemText
,
544 ARRAYSIZE(ListUi
->CurrentItemText
));
547 if ((strlen(ListUi
->CurrentItemText
) > 0) && (tolower(ListUi
->CurrentItemText
[0]) == AsciiChar
) &&
548 (List
->CurrentEntry
->Entry
.Flink
!= &List
->ListHead
))
550 ScrollDownGenericList(ListUi
);
551 ListEntry
= List
->CurrentEntry
;
553 ListUi
->CurrentItemText
[0] = ANSI_NULL
;
554 if (ListUi
->GetEntryDescriptionProc
)
556 ListUi
->GetEntryDescriptionProc(ListEntry
,
557 ListUi
->CurrentItemText
,
558 ARRAYSIZE(ListUi
->CurrentItemText
));
561 if ((strlen(ListUi
->CurrentItemText
) > 0) && (tolower(ListUi
->CurrentItemText
[0]) == AsciiChar
))
565 while (List
->CurrentEntry
->Entry
.Blink
!= &List
->ListHead
)
566 ScrollUpGenericList(ListUi
);
568 ListEntry
= List
->CurrentEntry
;
572 ListUi
->CurrentItemText
[0] = ANSI_NULL
;
573 if (ListUi
->GetEntryDescriptionProc
)
575 ListUi
->GetEntryDescriptionProc(ListEntry
,
576 ListUi
->CurrentItemText
,
577 ARRAYSIZE(ListUi
->CurrentItemText
));
580 if ((strlen(ListUi
->CurrentItemText
) > 0) && (tolower(ListUi
->CurrentItemText
[0]) == AsciiChar
))
586 if (List
->CurrentEntry
->Entry
.Flink
== &List
->ListHead
)
589 ScrollDownGenericList(ListUi
);
590 ListEntry
= List
->CurrentEntry
;
595 while (List
->CurrentEntry
->Entry
.Blink
!= &List
->ListHead
)
597 if (List
->CurrentEntry
!= OldListEntry
)
598 ScrollUpGenericList(ListUi
);
605 DrawListEntries(ListUi
);
606 DrawScrollBarGenericList(ListUi
);
608 ListUi
->Redraw
= TRUE
;