Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygengenlist.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2004 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* COPYRIGHT: See COPYING in the top level directory 00020 * PROJECT: ReactOS text-mode setup 00021 * FILE: subsys/system/usetup/genlist.c 00022 * PURPOSE: Generic list functions 00023 * PROGRAMMER: Eric Kohl 00024 * Christoph von Wittich <christoph at reactos.org> 00025 */ 00026 00027 /* INCLUDES *****************************************************************/ 00028 00029 #include "usetup.h" 00030 00031 #define NDEBUG 00032 #include <debug.h> 00033 00034 /* FUNCTIONS ****************************************************************/ 00035 00036 typedef struct _GENERIC_LIST_ENTRY 00037 { 00038 LIST_ENTRY Entry; 00039 PGENERIC_LIST List; 00040 PVOID UserData; 00041 CHAR Text[1]; 00042 } GENERIC_LIST_ENTRY; 00043 00044 00045 typedef struct _GENERIC_LIST 00046 { 00047 LIST_ENTRY ListHead; 00048 00049 PLIST_ENTRY FirstShown; 00050 PLIST_ENTRY LastShown; 00051 SHORT Left; 00052 SHORT Top; 00053 SHORT Right; 00054 SHORT Bottom; 00055 BOOL Redraw; 00056 00057 PGENERIC_LIST_ENTRY CurrentEntry; 00058 PGENERIC_LIST_ENTRY BackupEntry; 00059 } GENERIC_LIST; 00060 00061 PGENERIC_LIST 00062 CreateGenericList(VOID) 00063 { 00064 PGENERIC_LIST List; 00065 00066 List = (PGENERIC_LIST)RtlAllocateHeap(ProcessHeap, 00067 0, 00068 sizeof(GENERIC_LIST)); 00069 if (List == NULL) 00070 return NULL; 00071 00072 InitializeListHead(&List->ListHead); 00073 00074 List->Left = 0; 00075 List->Top = 0; 00076 List->Right = 0; 00077 List->Bottom = 0; 00078 List->Redraw = TRUE; 00079 00080 List->CurrentEntry = NULL; 00081 00082 return List; 00083 } 00084 00085 00086 VOID 00087 DestroyGenericList(PGENERIC_LIST List, 00088 BOOLEAN FreeUserData) 00089 { 00090 PGENERIC_LIST_ENTRY ListEntry; 00091 PLIST_ENTRY Entry; 00092 00093 /* Release list entries */ 00094 while (!IsListEmpty (&List->ListHead)) 00095 { 00096 Entry = RemoveHeadList (&List->ListHead); 00097 ListEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry); 00098 00099 /* Release user data */ 00100 if (FreeUserData && ListEntry->UserData != NULL) 00101 RtlFreeHeap (ProcessHeap, 0, ListEntry->UserData); 00102 00103 /* Release list entry */ 00104 RtlFreeHeap (ProcessHeap, 0, ListEntry); 00105 } 00106 00107 /* Release list head */ 00108 RtlFreeHeap (ProcessHeap, 0, List); 00109 } 00110 00111 00112 BOOLEAN 00113 AppendGenericListEntry(PGENERIC_LIST List, 00114 PCHAR Text, 00115 PVOID UserData, 00116 BOOLEAN Current) 00117 { 00118 PGENERIC_LIST_ENTRY Entry; 00119 00120 Entry = (PGENERIC_LIST_ENTRY)RtlAllocateHeap(ProcessHeap, 00121 0, 00122 sizeof(GENERIC_LIST_ENTRY) + strlen(Text)); 00123 if (Entry == NULL) 00124 return FALSE; 00125 00126 strcpy (Entry->Text, Text); 00127 Entry->List = List; 00128 Entry->UserData = UserData; 00129 00130 InsertTailList(&List->ListHead, 00131 &Entry->Entry); 00132 00133 if (Current || List->CurrentEntry == NULL) 00134 { 00135 List->CurrentEntry = Entry; 00136 } 00137 00138 return TRUE; 00139 } 00140 00141 00142 static VOID 00143 DrawListFrame(PGENERIC_LIST GenericList) 00144 { 00145 COORD coPos; 00146 DWORD Written; 00147 SHORT i; 00148 00149 /* Draw upper left corner */ 00150 coPos.X = GenericList->Left; 00151 coPos.Y = GenericList->Top; 00152 FillConsoleOutputCharacterA (StdOutput, 00153 0xDA, // '+', 00154 1, 00155 coPos, 00156 &Written); 00157 00158 /* Draw upper edge */ 00159 coPos.X = GenericList->Left + 1; 00160 coPos.Y = GenericList->Top; 00161 FillConsoleOutputCharacterA (StdOutput, 00162 0xC4, // '-', 00163 GenericList->Right - GenericList->Left - 1, 00164 coPos, 00165 &Written); 00166 00167 /* Draw upper right corner */ 00168 coPos.X = GenericList->Right; 00169 coPos.Y = GenericList->Top; 00170 FillConsoleOutputCharacterA (StdOutput, 00171 0xBF, // '+', 00172 1, 00173 coPos, 00174 &Written); 00175 00176 /* Draw left and right edge */ 00177 for (i = GenericList->Top + 1; i < GenericList->Bottom; i++) 00178 { 00179 coPos.X = GenericList->Left; 00180 coPos.Y = i; 00181 FillConsoleOutputCharacterA (StdOutput, 00182 0xB3, // '|', 00183 1, 00184 coPos, 00185 &Written); 00186 00187 coPos.X = GenericList->Right; 00188 FillConsoleOutputCharacterA (StdOutput, 00189 0xB3, //'|', 00190 1, 00191 coPos, 00192 &Written); 00193 } 00194 00195 /* Draw lower left corner */ 00196 coPos.X = GenericList->Left; 00197 coPos.Y = GenericList->Bottom; 00198 FillConsoleOutputCharacterA (StdOutput, 00199 0xC0, // '+', 00200 1, 00201 coPos, 00202 &Written); 00203 00204 /* Draw lower edge */ 00205 coPos.X = GenericList->Left + 1; 00206 coPos.Y = GenericList->Bottom; 00207 FillConsoleOutputCharacterA (StdOutput, 00208 0xC4, // '-', 00209 GenericList->Right - GenericList->Left - 1, 00210 coPos, 00211 &Written); 00212 00213 /* Draw lower right corner */ 00214 coPos.X = GenericList->Right; 00215 coPos.Y = GenericList->Bottom; 00216 FillConsoleOutputCharacterA (StdOutput, 00217 0xD9, // '+', 00218 1, 00219 coPos, 00220 &Written); 00221 } 00222 00223 00224 static VOID 00225 DrawListEntries(PGENERIC_LIST GenericList) 00226 { 00227 PGENERIC_LIST_ENTRY ListEntry; 00228 PLIST_ENTRY Entry; 00229 COORD coPos; 00230 DWORD Written; 00231 USHORT Width; 00232 00233 coPos.X = GenericList->Left + 1; 00234 coPos.Y = GenericList->Top + 1; 00235 Width = GenericList->Right - GenericList->Left - 1; 00236 00237 Entry = GenericList->FirstShown; 00238 while (Entry != &GenericList->ListHead) 00239 { 00240 ListEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry); 00241 00242 if (coPos.Y == GenericList->Bottom) 00243 break; 00244 GenericList->LastShown = Entry; 00245 00246 FillConsoleOutputAttribute (StdOutput, 00247 (GenericList->CurrentEntry == ListEntry) ? 00248 FOREGROUND_BLUE | BACKGROUND_WHITE : 00249 FOREGROUND_WHITE | BACKGROUND_BLUE, 00250 Width, 00251 coPos, 00252 &Written); 00253 00254 FillConsoleOutputCharacterA (StdOutput, 00255 ' ', 00256 Width, 00257 coPos, 00258 &Written); 00259 00260 coPos.X++; 00261 WriteConsoleOutputCharacterA (StdOutput, 00262 ListEntry->Text, 00263 min (strlen(ListEntry->Text), (SIZE_T)Width - 2), 00264 coPos, 00265 &Written); 00266 coPos.X--; 00267 00268 coPos.Y++; 00269 Entry = Entry->Flink; 00270 } 00271 00272 while (coPos.Y < GenericList->Bottom) 00273 { 00274 FillConsoleOutputAttribute (StdOutput, 00275 FOREGROUND_WHITE | BACKGROUND_BLUE, 00276 Width, 00277 coPos, 00278 &Written); 00279 00280 FillConsoleOutputCharacterA (StdOutput, 00281 ' ', 00282 Width, 00283 coPos, 00284 &Written); 00285 coPos.Y++; 00286 } 00287 } 00288 00289 static VOID 00290 DrawScrollBarGenericList(PGENERIC_LIST GenericList) 00291 { 00292 COORD coPos; 00293 DWORD Written; 00294 00295 coPos.X = GenericList->Right + 1; 00296 coPos.Y = GenericList->Top; 00297 00298 if (GenericList->FirstShown != GenericList->ListHead.Flink) 00299 { 00300 FillConsoleOutputCharacterA (StdOutput, 00301 '\x18', 00302 1, 00303 coPos, 00304 &Written); 00305 } 00306 else 00307 { 00308 FillConsoleOutputCharacterA (StdOutput, 00309 ' ', 00310 1, 00311 coPos, 00312 &Written); 00313 } 00314 00315 coPos.Y = GenericList->Bottom; 00316 if (GenericList->LastShown != GenericList->ListHead.Blink) 00317 { 00318 FillConsoleOutputCharacterA (StdOutput, 00319 '\x19', 00320 1, 00321 coPos, 00322 &Written); 00323 } 00324 else 00325 { 00326 FillConsoleOutputCharacterA (StdOutput, 00327 ' ', 00328 1, 00329 coPos, 00330 &Written); 00331 } 00332 } 00333 00334 VOID 00335 DrawGenericList(PGENERIC_LIST List, 00336 SHORT Left, 00337 SHORT Top, 00338 SHORT Right, 00339 SHORT Bottom) 00340 { 00341 List->FirstShown = List->ListHead.Flink; 00342 List->Left = Left; 00343 List->Top = Top; 00344 List->Right = Right; 00345 List->Bottom = Bottom; 00346 00347 DrawListFrame(List); 00348 00349 if (IsListEmpty(&List->ListHead)) 00350 return; 00351 00352 DrawListEntries(List); 00353 DrawScrollBarGenericList(List); 00354 } 00355 00356 VOID 00357 ScrollPageDownGenericList (PGENERIC_LIST List) 00358 { 00359 SHORT i; 00360 00361 /* Suspend auto-redraw */ 00362 List->Redraw = FALSE; 00363 00364 for (i = List->Top + 1; i < List->Bottom - 1; i++) 00365 { 00366 ScrollDownGenericList (List); 00367 } 00368 00369 /* Update user interface */ 00370 DrawListEntries(List); 00371 DrawScrollBarGenericList(List); 00372 00373 /* Re enable auto-redraw */ 00374 List->Redraw = TRUE; 00375 } 00376 00377 VOID 00378 ScrollPageUpGenericList (PGENERIC_LIST List) 00379 { 00380 SHORT i; 00381 00382 /* Suspend auto-redraw */ 00383 List->Redraw = FALSE; 00384 00385 for (i = List->Bottom - 1; i > List->Top + 1; i--) 00386 { 00387 ScrollUpGenericList (List); 00388 } 00389 00390 /* Update user interface */ 00391 DrawListEntries(List); 00392 DrawScrollBarGenericList(List); 00393 00394 /* Re enable auto-redraw */ 00395 List->Redraw = TRUE; 00396 } 00397 00398 VOID 00399 ScrollDownGenericList (PGENERIC_LIST List) 00400 { 00401 PLIST_ENTRY Entry; 00402 00403 if (List->CurrentEntry == NULL) 00404 return; 00405 00406 if (List->CurrentEntry->Entry.Flink != &List->ListHead) 00407 { 00408 Entry = List->CurrentEntry->Entry.Flink; 00409 if (List->LastShown == &List->CurrentEntry->Entry) 00410 { 00411 List->FirstShown = List->FirstShown->Flink; 00412 List->LastShown = List->LastShown->Flink; 00413 } 00414 List->CurrentEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry); 00415 00416 if (List->Redraw) 00417 { 00418 DrawListEntries(List); 00419 DrawScrollBarGenericList(List); 00420 } 00421 } 00422 } 00423 00424 00425 VOID 00426 ScrollToPositionGenericList (PGENERIC_LIST List, ULONG uIndex) 00427 { 00428 PLIST_ENTRY Entry; 00429 ULONG uCount = 0; 00430 00431 if (List->CurrentEntry == NULL || uIndex == 0) 00432 return; 00433 00434 do 00435 { 00436 if (List->CurrentEntry->Entry.Flink != &List->ListHead) 00437 { 00438 Entry = List->CurrentEntry->Entry.Flink; 00439 if (List->LastShown == &List->CurrentEntry->Entry) 00440 { 00441 List->FirstShown = List->FirstShown->Flink; 00442 List->LastShown = List->LastShown->Flink; 00443 } 00444 List->CurrentEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry); 00445 } 00446 uCount++; 00447 } 00448 while (uIndex != uCount); 00449 00450 if (List->Redraw) 00451 { 00452 DrawListEntries(List); 00453 DrawScrollBarGenericList(List); 00454 } 00455 } 00456 00457 00458 VOID 00459 ScrollUpGenericList (PGENERIC_LIST List) 00460 { 00461 PLIST_ENTRY Entry; 00462 00463 if (List->CurrentEntry == NULL) 00464 return; 00465 00466 if (List->CurrentEntry->Entry.Blink != &List->ListHead) 00467 { 00468 Entry = List->CurrentEntry->Entry.Blink; 00469 if (List->FirstShown == &List->CurrentEntry->Entry) 00470 { 00471 List->FirstShown = List->FirstShown->Blink; 00472 List->LastShown = List->LastShown->Blink; 00473 } 00474 List->CurrentEntry = CONTAINING_RECORD (Entry, GENERIC_LIST_ENTRY, Entry); 00475 00476 if (List->Redraw) 00477 { 00478 DrawListEntries(List); 00479 DrawScrollBarGenericList(List); 00480 } 00481 } 00482 } 00483 00484 00485 VOID 00486 SetCurrentListEntry(PGENERIC_LIST List, PGENERIC_LIST_ENTRY Entry) 00487 { 00488 if (Entry->List != List) 00489 return; 00490 List->CurrentEntry = Entry; 00491 } 00492 00493 00494 PGENERIC_LIST_ENTRY 00495 GetCurrentListEntry(PGENERIC_LIST List) 00496 { 00497 return List->CurrentEntry; 00498 } 00499 00500 00501 PGENERIC_LIST_ENTRY 00502 GetFirstListEntry(PGENERIC_LIST List) 00503 { 00504 PLIST_ENTRY Entry = List->ListHead.Flink; 00505 00506 if (Entry == &List->ListHead) 00507 return NULL; 00508 return CONTAINING_RECORD(Entry, GENERIC_LIST_ENTRY, Entry); 00509 } 00510 00511 00512 PGENERIC_LIST_ENTRY 00513 GetNextListEntry(PGENERIC_LIST_ENTRY Entry) 00514 { 00515 PLIST_ENTRY Next = Entry->Entry.Flink; 00516 00517 if (Next == &Entry->List->ListHead) 00518 return NULL; 00519 return CONTAINING_RECORD(Next, GENERIC_LIST_ENTRY, Entry); 00520 } 00521 00522 00523 PVOID 00524 GetListEntryUserData(PGENERIC_LIST_ENTRY List) 00525 { 00526 return List->UserData; 00527 } 00528 00529 00530 LPCSTR 00531 GetListEntryText(PGENERIC_LIST_ENTRY List) 00532 { 00533 return List->Text; 00534 } 00535 00536 00537 VOID 00538 GenericListKeyPress (PGENERIC_LIST GenericList, CHAR AsciChar) 00539 { 00540 PGENERIC_LIST_ENTRY ListEntry; 00541 PGENERIC_LIST_ENTRY OldListEntry; 00542 BOOLEAN Flag = FALSE; 00543 00544 ListEntry = GenericList->CurrentEntry; 00545 OldListEntry = GenericList->CurrentEntry; 00546 00547 GenericList->Redraw = FALSE; 00548 00549 if ((strlen(ListEntry->Text) > 0) && (tolower(ListEntry->Text[0]) == AsciChar) && 00550 (GenericList->CurrentEntry->Entry.Flink != &GenericList->ListHead)) 00551 { 00552 ScrollDownGenericList(GenericList); 00553 ListEntry = GenericList->CurrentEntry; 00554 00555 if ((strlen(ListEntry->Text) > 0) && (tolower(ListEntry->Text[0]) == AsciChar)) 00556 goto End; 00557 } 00558 00559 while (GenericList->CurrentEntry->Entry.Blink != &GenericList->ListHead) 00560 ScrollUpGenericList(GenericList); 00561 00562 ListEntry = GenericList->CurrentEntry; 00563 00564 for (;;) 00565 { 00566 if ((strlen(ListEntry->Text) > 0) && (tolower(ListEntry->Text[0]) == AsciChar)) 00567 { 00568 Flag = TRUE; 00569 break; 00570 } 00571 00572 if (GenericList->CurrentEntry->Entry.Flink == &GenericList->ListHead) 00573 break; 00574 00575 ScrollDownGenericList(GenericList); 00576 ListEntry = GenericList->CurrentEntry; 00577 } 00578 00579 if (!Flag) 00580 { 00581 while (GenericList->CurrentEntry->Entry.Blink != &GenericList->ListHead) 00582 { 00583 if (GenericList->CurrentEntry != OldListEntry) 00584 ScrollUpGenericList(GenericList); 00585 else 00586 break; 00587 } 00588 } 00589 End: 00590 DrawListEntries(GenericList); 00591 DrawScrollBarGenericList(GenericList); 00592 00593 GenericList->Redraw = TRUE; 00594 } 00595 00596 00597 VOID 00598 SaveGenericListState(PGENERIC_LIST List) 00599 { 00600 List->BackupEntry = List->CurrentEntry; 00601 } 00602 00603 00604 VOID 00605 RestoreGenericListState(PGENERIC_LIST List) 00606 { 00607 List->CurrentEntry = List->BackupEntry; 00608 } 00609 00610 /* EOF */ Generated on Mon May 28 2012 04:17:51 for ReactOS by
1.7.6.1
|