提交 7b7d36a8 编写于 作者: M Marvin Häuser

OpenCanopy: Replace linked lists with arrays for GUI object children

上级 06991a81
...@@ -107,7 +107,8 @@ EFI_STATUS ...@@ -107,7 +107,8 @@ EFI_STATUS
BootPickerViewInitialize ( BootPickerViewInitialize (
OUT GUI_DRAWING_CONTEXT *DrawContext, OUT GUI_DRAWING_CONTEXT *DrawContext,
IN BOOT_PICKER_GUI_CONTEXT *GuiContext, IN BOOT_PICKER_GUI_CONTEXT *GuiContext,
IN GUI_CURSOR_GET_IMAGE GetCursorImage IN GUI_CURSOR_GET_IMAGE GetCursorImage,
IN UINT8 NumBootEntries
); );
VOID VOID
...@@ -116,10 +117,11 @@ BootPickerViewLateInitialize ( ...@@ -116,10 +117,11 @@ BootPickerViewLateInitialize (
); );
EFI_STATUS EFI_STATUS
BootPickerEntriesAdd ( BootPickerEntriesSet (
IN OC_PICKER_CONTEXT *Context, IN OC_PICKER_CONTEXT *Context,
IN BOOT_PICKER_GUI_CONTEXT *GuiContext, IN BOOT_PICKER_GUI_CONTEXT *GuiContext,
IN OC_BOOT_ENTRY *Entry, IN OC_BOOT_ENTRY *Entry,
IN UINT8 EntryIndex,
IN BOOLEAN Default IN BOOLEAN Default
); );
......
...@@ -109,7 +109,8 @@ OcShowMenuByOc ( ...@@ -109,7 +109,8 @@ OcShowMenuByOc (
Status = BootPickerViewInitialize ( Status = BootPickerViewInitialize (
&mDrawContext, &mDrawContext,
&mGuiContext, &mGuiContext,
InternalGetCursorImage InternalGetCursorImage,
(UINT8) BootContext->BootEntryCount
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
OcShowMenuByOcLeave (); OcShowMenuByOcLeave ();
...@@ -117,10 +118,11 @@ OcShowMenuByOc ( ...@@ -117,10 +118,11 @@ OcShowMenuByOc (
} }
for (Index = 0; Index < BootContext->BootEntryCount; ++Index) { for (Index = 0; Index < BootContext->BootEntryCount; ++Index) {
Status = BootPickerEntriesAdd ( Status = BootPickerEntriesSet (
BootContext->PickerContext, BootContext->PickerContext,
&mGuiContext, &mGuiContext,
BootEntries[Index], BootEntries[Index],
(UINT8) Index + 1,
Index == BootContext->DefaultEntry->EntryIndex - 1 Index == BootContext->DefaultEntry->EntryIndex - 1
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
......
...@@ -141,7 +141,7 @@ GuiObjDrawDelegate ( ...@@ -141,7 +141,7 @@ GuiObjDrawDelegate (
{ {
BOOLEAN Result; BOOLEAN Result;
LIST_ENTRY *ChildEntry; UINTN Index;
GUI_OBJ_CHILD *Child; GUI_OBJ_CHILD *Child;
UINT32 ChildDrawOffsetX; UINT32 ChildDrawOffsetX;
...@@ -158,12 +158,8 @@ GuiObjDrawDelegate ( ...@@ -158,12 +158,8 @@ GuiObjDrawDelegate (
ASSERT (Height <= This->Height); ASSERT (Height <= This->Height);
ASSERT (DrawContext != NULL); ASSERT (DrawContext != NULL);
for ( for (Index = 0; Index < This->NumChildren; ++Index) {
ChildEntry = GetPreviousNode (&This->Children, &This->Children); Child = This->Children[Index];
!IsNull (&This->Children, ChildEntry);
ChildEntry = GetPreviousNode (&This->Children, ChildEntry)
) {
Child = BASE_CR (ChildEntry, GUI_OBJ_CHILD, Link);
ChildDrawOffsetX = OffsetX; ChildDrawOffsetX = OffsetX;
ChildDrawWidth = Width; ChildDrawWidth = Width;
...@@ -220,8 +216,8 @@ GuiObjDelegatePtrEvent ( ...@@ -220,8 +216,8 @@ GuiObjDelegatePtrEvent (
IN INT64 OffsetY IN INT64 OffsetY
) )
{ {
UINTN Index;
GUI_OBJ *Obj; GUI_OBJ *Obj;
LIST_ENTRY *ChildEntry;
GUI_OBJ_CHILD *Child; GUI_OBJ_CHILD *Child;
ASSERT (This != NULL); ASSERT (This != NULL);
...@@ -229,12 +225,8 @@ GuiObjDelegatePtrEvent ( ...@@ -229,12 +225,8 @@ GuiObjDelegatePtrEvent (
ASSERT (This->Height > OffsetY); ASSERT (This->Height > OffsetY);
ASSERT (DrawContext != NULL); ASSERT (DrawContext != NULL);
for ( for (Index = 0; Index < This->NumChildren; ++Index) {
ChildEntry = GetFirstNode (&This->Children); Child = This->Children[Index];
!IsNull (&This->Children, ChildEntry);
ChildEntry = GetNextNode (&This->Children, ChildEntry)
) {
Child = BASE_CR (ChildEntry, GUI_OBJ_CHILD, Link);
if (OffsetX < Child->Obj.OffsetX if (OffsetX < Child->Obj.OffsetX
|| OffsetX >= Child->Obj.OffsetX + Child->Obj.Width || OffsetX >= Child->Obj.OffsetX + Child->Obj.Width
|| OffsetY < Child->Obj.OffsetY || OffsetY < Child->Obj.OffsetY
...@@ -937,6 +929,7 @@ GuiGetBaseCoords ( ...@@ -937,6 +929,7 @@ GuiGetBaseCoords (
GUI_OBJ_CHILD *ChildObj; GUI_OBJ_CHILD *ChildObj;
INT64 X; INT64 X;
INT64 Y; INT64 Y;
UINT32 Index;
ASSERT (This != NULL); ASSERT (This != NULL);
ASSERT (DrawContext != NULL); ASSERT (DrawContext != NULL);
...@@ -955,7 +948,15 @@ GuiGetBaseCoords ( ...@@ -955,7 +948,15 @@ GuiGetBaseCoords (
ChildObj = BASE_CR (Obj, GUI_OBJ_CHILD, Obj); ChildObj = BASE_CR (Obj, GUI_OBJ_CHILD, Obj);
Obj = ChildObj->Parent; Obj = ChildObj->Parent;
ASSERT (Obj != NULL); ASSERT (Obj != NULL);
ASSERT (IsNodeInList (&Obj->Children, &ChildObj->Link));
DEBUG_CODE_BEGIN ();
for (Index = 0; Index < Obj->NumChildren; ++Index) {
if (Obj->Children[Index] == ChildObj) {
break;
}
}
ASSERT (Index != Obj->NumChildren);
DEBUG_CODE_END ();
} }
*BaseX = X; *BaseX = X;
......
...@@ -79,6 +79,8 @@ typedef struct { ...@@ -79,6 +79,8 @@ typedef struct {
GUI_ANIMATE Animate; GUI_ANIMATE Animate;
} GUI_ANIMATION; } GUI_ANIMATION;
typedef struct GUI_OBJ_CHILD_ GUI_OBJ_CHILD;
struct GUI_OBJ_ { struct GUI_OBJ_ {
INT64 OffsetX; INT64 OffsetX;
INT64 OffsetY; INT64 OffsetY;
...@@ -87,14 +89,14 @@ struct GUI_OBJ_ { ...@@ -87,14 +89,14 @@ struct GUI_OBJ_ {
GUI_OBJ_DRAW Draw; GUI_OBJ_DRAW Draw;
GUI_OBJ_PTR_EVENT PtrEvent; GUI_OBJ_PTR_EVENT PtrEvent;
GUI_OBJ_KEY_EVENT KeyEvent; GUI_OBJ_KEY_EVENT KeyEvent;
LIST_ENTRY Children; UINT32 NumChildren;
GUI_OBJ_CHILD **Children;
}; };
typedef struct { struct GUI_OBJ_CHILD_ {
LIST_ENTRY Link;
GUI_OBJ *Parent; GUI_OBJ *Parent;
GUI_OBJ Obj; GUI_OBJ Obj;
} GUI_OBJ_CHILD; };
typedef struct { typedef struct {
UINT32 Width; UINT32 Width;
......
...@@ -47,6 +47,19 @@ STATIC UINT8 mBootPickerOpacity = 0xFF; ...@@ -47,6 +47,19 @@ STATIC UINT8 mBootPickerOpacity = 0xFF;
GLOBAL_REMOVE_IF_UNREFERENCED INT64 mBackgroundImageOffsetX; GLOBAL_REMOVE_IF_UNREFERENCED INT64 mBackgroundImageOffsetX;
GLOBAL_REMOVE_IF_UNREFERENCED INT64 mBackgroundImageOffsetY; GLOBAL_REMOVE_IF_UNREFERENCED INT64 mBackgroundImageOffsetY;
STATIC
GUI_VOLUME_ENTRY *
InternalGetVolumeEntry (
IN UINT32 Index
)
{
ASSERT (Index > 0);
ASSERT (Index < mBootPicker.Hdr.Obj.NumChildren);
return (GUI_VOLUME_ENTRY *) (
mBootPicker.Hdr.Obj.Children[Index]
);
}
VOID VOID
GuiDrawChildImage ( GuiDrawChildImage (
IN CONST GUI_IMAGE *Image, IN CONST GUI_IMAGE *Image,
...@@ -212,36 +225,30 @@ VOID ...@@ -212,36 +225,30 @@ VOID
InternalBootPickerSelectEntry ( InternalBootPickerSelectEntry (
IN OUT GUI_VOLUME_PICKER *This, IN OUT GUI_VOLUME_PICKER *This,
IN OUT GUI_DRAWING_CONTEXT *DrawContext, IN OUT GUI_DRAWING_CONTEXT *DrawContext,
IN GUI_VOLUME_ENTRY *NewEntry IN UINT32 NewIndex
) )
{ {
CONST GUI_OBJ *VolumeEntryObj; CONST GUI_VOLUME_ENTRY *NewEntry;
LIST_ENTRY *SelectorNode;
GUI_OBJ_CHILD *Selector;
ASSERT (This != NULL); ASSERT (This != NULL);
ASSERT (NewEntry != NULL); ASSERT (NewIndex > 0);
ASSERT (IsNodeInList (&This->Hdr.Obj.Children, &NewEntry->Hdr.Link)); ASSERT (NewIndex < mBootPicker.Hdr.Obj.NumChildren);
This->SelectedEntry = NewEntry; This->SelectedIndex = NewIndex;
VolumeEntryObj = &NewEntry->Hdr.Obj; NewEntry = (CONST GUI_VOLUME_ENTRY *) mBootPicker.Hdr.Obj.Children[NewIndex];
SelectorNode = This->Hdr.Obj.Children.BackLink; ASSERT (mBootPickerSelector.Hdr.Obj.Width <= NewEntry->Hdr.Obj.Width);
ASSERT (SelectorNode != NULL); ASSERT_EQUALS (This->Hdr.Obj.Height, mBootPickerSelector.Hdr.Obj.OffsetY + mBootPickerSelector.Hdr.Obj.Height);
Selector = BASE_CR (SelectorNode, GUI_OBJ_CHILD, Link); mBootPickerSelector.Hdr.Obj.OffsetX = NewEntry->Hdr.Obj.OffsetX;
ASSERT (Selector->Obj.Width <= VolumeEntryObj->Width); mBootPickerSelector.Hdr.Obj.OffsetX += (NewEntry->Hdr.Obj.Width - mBootPickerSelector.Hdr.Obj.Width) / 2;
ASSERT_EQUALS (This->Hdr.Obj.Height, Selector->Obj.OffsetY + Selector->Obj.Height);
Selector->Obj.OffsetX = VolumeEntryObj->OffsetX;
Selector->Obj.OffsetX += (VolumeEntryObj->Width - Selector->Obj.Width) / 2;
if (DrawContext != NULL) { if (DrawContext != NULL) {
// //
// Set voice timeout to N frames from now. // Set voice timeout to N frames from now.
// //
DrawContext->GuiContext->AudioPlaybackTimeout = OC_VOICE_OVER_IDLE_TIMEOUT_MS; DrawContext->GuiContext->AudioPlaybackTimeout = OC_VOICE_OVER_IDLE_TIMEOUT_MS;
DrawContext->GuiContext->BootEntry = This->SelectedEntry->Context; DrawContext->GuiContext->BootEntry = NewEntry->Context;
} }
} }
...@@ -253,13 +260,13 @@ InternelBootPickerScrollSelected ( ...@@ -253,13 +260,13 @@ InternelBootPickerScrollSelected (
CONST GUI_VOLUME_ENTRY *SelectedEntry; CONST GUI_VOLUME_ENTRY *SelectedEntry;
INT64 EntryOffsetX; INT64 EntryOffsetX;
if (mBootPicker.SelectedEntry == NULL) { if (mBootPicker.Hdr.Obj.NumChildren == 1) {
return 0; return 0;
} }
// //
// If the selected entry is outside of the view, scroll it accordingly. // If the selected entry is outside of the view, scroll it accordingly.
// //
SelectedEntry = mBootPicker.SelectedEntry; SelectedEntry = InternalGetVolumeEntry (mBootPicker.SelectedIndex);
EntryOffsetX = mBootPicker.Hdr.Obj.OffsetX + SelectedEntry->Hdr.Obj.OffsetX; EntryOffsetX = mBootPicker.Hdr.Obj.OffsetX + SelectedEntry->Hdr.Obj.OffsetX;
if (EntryOffsetX < 0) { if (EntryOffsetX < 0) {
...@@ -329,26 +336,28 @@ InternalBootPickerChangeEntry ( ...@@ -329,26 +336,28 @@ InternalBootPickerChangeEntry (
IN OUT GUI_DRAWING_CONTEXT *DrawContext, IN OUT GUI_DRAWING_CONTEXT *DrawContext,
IN INT64 BaseX, IN INT64 BaseX,
IN INT64 BaseY, IN INT64 BaseY,
IN GUI_VOLUME_ENTRY *NewEntry IN UINT32 NewIndex
) )
{ {
GUI_VOLUME_ENTRY *PrevEntry; CONST GUI_VOLUME_ENTRY *NewEntry;
INT64 ScrollOffset; CONST GUI_VOLUME_ENTRY *PrevEntry;
INT64 ScrollOffset;
ASSERT (This != NULL); ASSERT (This != NULL);
ASSERT (DrawContext != NULL); ASSERT (DrawContext != NULL);
ASSERT (NewEntry != NULL); ASSERT (NewIndex > 0);
ASSERT (IsNodeInList (&This->Hdr.Obj.Children, &NewEntry->Hdr.Link)); ASSERT (NewIndex < This->Hdr.Obj.NumChildren);
// //
// The caller must guarantee the entry is actually new for performance // The caller must guarantee the entry is actually new for performance
// reasons. // reasons.
// //
ASSERT (This->SelectedEntry != NewEntry); ASSERT (This->SelectedIndex != NewIndex);
// //
// Redraw the two now (un-)selected entries. // Redraw the two now (un-)selected entries.
// //
PrevEntry = This->SelectedEntry; NewEntry = InternalGetVolumeEntry (NewIndex);
InternalBootPickerSelectEntry (This, DrawContext, NewEntry); PrevEntry = InternalGetVolumeEntry (mBootPicker.SelectedIndex);
InternalBootPickerSelectEntry (This, DrawContext, NewIndex);
ScrollOffset = InternelBootPickerScrollSelected (); ScrollOffset = InternelBootPickerScrollSelected ();
if (ScrollOffset == 0) { if (ScrollOffset == 0) {
...@@ -395,50 +404,50 @@ InternalBootPickerKeyEvent ( ...@@ -395,50 +404,50 @@ InternalBootPickerKeyEvent (
) )
{ {
GUI_VOLUME_PICKER *Picker; GUI_VOLUME_PICKER *Picker;
GUI_VOLUME_ENTRY *PrevEntry; CONST GUI_VOLUME_ENTRY *SelectedEntry;
LIST_ENTRY *NextLink;
GUI_VOLUME_ENTRY *NextEntry;
ASSERT (This != NULL); ASSERT (This != NULL);
ASSERT (GuiContext != NULL); ASSERT (GuiContext != NULL);
ASSERT (DrawContext != NULL); ASSERT (DrawContext != NULL);
Picker = BASE_CR (This, GUI_VOLUME_PICKER, Hdr.Obj); Picker = BASE_CR (This, GUI_VOLUME_PICKER, Hdr.Obj);
PrevEntry = Picker->SelectedEntry;
ASSERT (PrevEntry != NULL);
if (Key == OC_INPUT_RIGHT) { if (Key == OC_INPUT_RIGHT) {
NextLink = GetNextNode (
&Picker->Hdr.Obj.Children,
&PrevEntry->Hdr.Link
);
// //
// Edge-case: The last child is the selector button. // Edge-case: The last child is the selector button.
// //
if (This->Children.BackLink != NextLink) { if (mBootPicker.SelectedIndex + 1 < mBootPicker.Hdr.Obj.NumChildren) {
// //
// Redraw the two now (un-)selected entries. // Redraw the two now (un-)selected entries.
// //
NextEntry = BASE_CR (NextLink, GUI_VOLUME_ENTRY, Hdr.Link); InternalBootPickerChangeEntry (
InternalBootPickerChangeEntry (Picker, DrawContext, BaseX, BaseY, NextEntry); Picker,
DrawContext,
BaseX,
BaseY,
mBootPicker.SelectedIndex + 1
);
} }
} else if (Key == OC_INPUT_LEFT) { } else if (Key == OC_INPUT_LEFT) {
NextLink = GetPreviousNode ( if (mBootPicker.SelectedIndex - 1 > 0) {
&Picker->Hdr.Obj.Children,
&PrevEntry->Hdr.Link
);
if (!IsNull (&This->Children, NextLink)) {
// //
// Redraw the two now (un-)selected entries. // Redraw the two now (un-)selected entries.
// //
NextEntry = BASE_CR (NextLink, GUI_VOLUME_ENTRY, Hdr.Link); InternalBootPickerChangeEntry (
InternalBootPickerChangeEntry (Picker, DrawContext, BaseX, BaseY, NextEntry); Picker,
DrawContext,
BaseX,
BaseY,
mBootPicker.SelectedIndex - 1
);
} }
} else if (Key == OC_INPUT_CONTINUE) { } else if (Key == OC_INPUT_CONTINUE) {
ASSERT (Picker->SelectedEntry != NULL); if (mBootPicker.Hdr.Obj.NumChildren > 1) {
Picker->SelectedEntry->Context->SetDefault = Modifier; SelectedEntry = InternalGetVolumeEntry (mBootPicker.SelectedIndex);
GuiContext->ReadyToBoot = TRUE; SelectedEntry->Context->SetDefault = Modifier;
ASSERT (GuiContext->BootEntry == Picker->SelectedEntry->Context); GuiContext->ReadyToBoot = TRUE;
ASSERT (GuiContext->BootEntry == SelectedEntry->Context);
}
} else if (mBootPickerOpacity != 0xFF) { } else if (mBootPickerOpacity != 0xFF) {
// //
// FIXME: Other keys are not allowed when boot picker is partially transparent. // FIXME: Other keys are not allowed when boot picker is partially transparent.
...@@ -548,7 +557,7 @@ InternalBootPickerEntryDraw ( ...@@ -548,7 +557,7 @@ InternalBootPickerEntryDraw (
// //
// There should be no children. // There should be no children.
// //
ASSERT (IsListEmpty (&This->Children)); ASSERT (This->NumChildren == 0);
} }
STATIC STATIC
...@@ -593,14 +602,14 @@ InternalBootPickerEntryPtrEvent ( ...@@ -593,14 +602,14 @@ InternalBootPickerEntryPtrEvent (
} }
if (Event == GuiPointerPrimaryDown) { if (Event == GuiPointerPrimaryDown) {
if (mBootPicker.SelectedEntry != Entry) { if (mBootPicker.SelectedIndex != Entry->Index) {
ASSERT (Entry->Hdr.Parent == &mBootPicker.Hdr.Obj); ASSERT (Entry->Hdr.Parent == &mBootPicker.Hdr.Obj);
InternalBootPickerChangeEntry ( InternalBootPickerChangeEntry (
&mBootPicker, &mBootPicker,
DrawContext, DrawContext,
BaseX - This->OffsetX, BaseX - This->OffsetX,
BaseY - This->OffsetY, BaseY - This->OffsetY,
Entry Entry->Index
); );
SameIter = TRUE; SameIter = TRUE;
} }
...@@ -609,7 +618,7 @@ InternalBootPickerEntryPtrEvent ( ...@@ -609,7 +618,7 @@ InternalBootPickerEntryPtrEvent (
// This must be ensured because the UI directs Move/Up events to the object // This must be ensured because the UI directs Move/Up events to the object
// Down had been sent to. // Down had been sent to.
// //
ASSERT (mBootPicker.SelectedEntry == Entry); ASSERT (mBootPicker.SelectedIndex == Entry->Index);
if (SameIter) { if (SameIter) {
SameIter = FALSE; SameIter = FALSE;
...@@ -621,7 +630,7 @@ InternalBootPickerEntryPtrEvent ( ...@@ -621,7 +630,7 @@ InternalBootPickerEntryPtrEvent (
// //
// There should be no children. // There should be no children.
// //
ASSERT (IsListEmpty (&This->Children)); ASSERT (This->NumChildren == 0);
return This; return This;
} }
...@@ -700,7 +709,7 @@ InternalBootPickerSelectorDraw ( ...@@ -700,7 +709,7 @@ InternalBootPickerSelectorDraw (
// //
// There should be no children. // There should be no children.
// //
ASSERT (IsListEmpty (&This->Children)); ASSERT (This->NumChildren == 0);
} }
VOID VOID
...@@ -750,7 +759,7 @@ InternalBootPickerLeftScrollDraw ( ...@@ -750,7 +759,7 @@ InternalBootPickerLeftScrollDraw (
// //
// There should be no children. // There should be no children.
// //
ASSERT (IsListEmpty (&This->Children)); ASSERT (This->NumChildren == 0);
} }
VOID VOID
...@@ -800,7 +809,7 @@ InternalBootPickerRightScrollDraw ( ...@@ -800,7 +809,7 @@ InternalBootPickerRightScrollDraw (
// //
// There should be no children. // There should be no children.
// //
ASSERT (IsListEmpty (&This->Children)); ASSERT (This->NumChildren == 0);
} }
GUI_OBJ * GUI_OBJ *
...@@ -826,7 +835,7 @@ InternalBootPickerSelectorPtrEvent ( ...@@ -826,7 +835,7 @@ InternalBootPickerSelectorPtrEvent (
// //
// There should be no children. // There should be no children.
// //
ASSERT (IsListEmpty (&This->Children)); ASSERT (This->NumChildren == 0);
Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj); Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj);
ButtonImage = &Context->Icons[ICON_SELECTOR][ICON_TYPE_BASE]; ButtonImage = &Context->Icons[ICON_SELECTOR][ICON_TYPE_BASE];
...@@ -843,8 +852,7 @@ InternalBootPickerSelectorPtrEvent ( ...@@ -843,8 +852,7 @@ InternalBootPickerSelectorPtrEvent (
); );
if (IsHit) { if (IsHit) {
if (Event == GuiPointerPrimaryUp) { if (Event == GuiPointerPrimaryUp) {
ASSERT (mBootPicker.SelectedEntry != NULL); ASSERT (Context->BootEntry == InternalGetVolumeEntry (mBootPicker.SelectedIndex)->Context);
ASSERT (Context->BootEntry == mBootPicker.SelectedEntry->Context);
Context->ReadyToBoot = TRUE; Context->ReadyToBoot = TRUE;
} else { } else {
ButtonImage = &Context->Icons[ICON_SELECTOR][ICON_TYPE_HELD]; ButtonImage = &Context->Icons[ICON_SELECTOR][ICON_TYPE_HELD];
...@@ -881,10 +889,10 @@ InternalBootPickerLeftScrollPtrEvent ( ...@@ -881,10 +889,10 @@ InternalBootPickerLeftScrollPtrEvent (
{ {
GUI_OBJ_CLICKABLE *Clickable; GUI_OBJ_CLICKABLE *Clickable;
CONST GUI_IMAGE *ButtonImage; CONST GUI_IMAGE *ButtonImage;
LIST_ENTRY *PrevEntry;
INT64 BootPickerX; INT64 BootPickerX;
INT64 BootPickerY; INT64 BootPickerY;
BOOLEAN IsHit; BOOLEAN IsHit;
CONST GUI_VOLUME_ENTRY *SelectedEntry;
ASSERT (This != NULL); ASSERT (This != NULL);
ASSERT (DrawContext != NULL); ASSERT (DrawContext != NULL);
...@@ -892,7 +900,7 @@ InternalBootPickerLeftScrollPtrEvent ( ...@@ -892,7 +900,7 @@ InternalBootPickerLeftScrollPtrEvent (
// //
// There should be no children. // There should be no children.
// //
ASSERT (IsListEmpty (&This->Children)); ASSERT (This->NumChildren == 0);
Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj); Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj);
ButtonImage = &Context->Icons[ICON_LEFT][ICON_TYPE_BASE]; ButtonImage = &Context->Icons[ICON_LEFT][ICON_TYPE_BASE];
...@@ -925,23 +933,21 @@ InternalBootPickerLeftScrollPtrEvent ( ...@@ -925,23 +933,21 @@ InternalBootPickerLeftScrollPtrEvent (
// If the selected entry is pushed off-screen by scrolling, select the // If the selected entry is pushed off-screen by scrolling, select the
// appropriate neighbour entry. // appropriate neighbour entry.
// //
if (mBootPicker.Hdr.Obj.OffsetX + (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * Context->Scale + mBootPicker.SelectedEntry->Hdr.Obj.OffsetX + mBootPicker.SelectedEntry->Hdr.Obj.Width > mBootPickerContainer.Obj.Width) { SelectedEntry = InternalGetVolumeEntry (mBootPicker.SelectedIndex);
if (mBootPicker.Hdr.Obj.OffsetX + (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * Context->Scale + SelectedEntry->Hdr.Obj.OffsetX + SelectedEntry->Hdr.Obj.Width > mBootPickerContainer.Obj.Width) {
// //
// The internal design ensures a selected entry cannot be off-screen, // The internal design ensures a selected entry cannot be off-screen,
// scrolling offsets it by at most one spot. // scrolling offsets it by at most one spot.
// //
PrevEntry = GetPreviousNode ( if (mBootPicker.SelectedIndex > 1) {
&mBootPicker.Hdr.Obj.Children,
&mBootPicker.SelectedEntry->Hdr.Link
);
if (!IsNull (&mBootPicker.Hdr.Obj.Children, PrevEntry)) {
InternalBootPickerSelectEntry ( InternalBootPickerSelectEntry (
&mBootPicker, &mBootPicker,
DrawContext, DrawContext,
BASE_CR (PrevEntry, GUI_VOLUME_ENTRY, Hdr.Link) mBootPicker.SelectedIndex - 1
); );
ASSERT (!(mBootPicker.Hdr.Obj.OffsetX + (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * Context->Scale + mBootPicker.SelectedEntry->Hdr.Obj.OffsetX + mBootPicker.SelectedEntry->Hdr.Obj.Width > mBootPickerContainer.Obj.Width)); SelectedEntry = InternalGetVolumeEntry (mBootPicker.SelectedIndex);
ASSERT (!(mBootPicker.Hdr.Obj.OffsetX + (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * Context->Scale + SelectedEntry->Hdr.Obj.OffsetX + SelectedEntry->Hdr.Obj.Width > mBootPickerContainer.Obj.Width));
} }
} }
// //
...@@ -989,8 +995,8 @@ InternalBootPickerRightScrollPtrEvent ( ...@@ -989,8 +995,8 @@ InternalBootPickerRightScrollPtrEvent (
CONST GUI_IMAGE *ButtonImage; CONST GUI_IMAGE *ButtonImage;
INT64 BootPickerX; INT64 BootPickerX;
INT64 BootPickerY; INT64 BootPickerY;
LIST_ENTRY *NextEntry;
BOOLEAN IsHit; BOOLEAN IsHit;
GUI_VOLUME_ENTRY *SelectedEntry;
ASSERT (This != NULL); ASSERT (This != NULL);
ASSERT (DrawContext != NULL); ASSERT (DrawContext != NULL);
...@@ -998,7 +1004,7 @@ InternalBootPickerRightScrollPtrEvent ( ...@@ -998,7 +1004,7 @@ InternalBootPickerRightScrollPtrEvent (
// //
// There should be no children. // There should be no children.
// //
ASSERT (IsListEmpty (&This->Children)); ASSERT (This->NumChildren == 0);
Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj); Clickable = BASE_CR (This, GUI_OBJ_CLICKABLE, Hdr.Obj);
ButtonImage = &Context->Icons[ICON_RIGHT][ICON_TYPE_BASE]; ButtonImage = &Context->Icons[ICON_RIGHT][ICON_TYPE_BASE];
...@@ -1029,24 +1035,22 @@ InternalBootPickerRightScrollPtrEvent ( ...@@ -1029,24 +1035,22 @@ InternalBootPickerRightScrollPtrEvent (
// If the selected entry is pushed off-screen by scrolling, select the // If the selected entry is pushed off-screen by scrolling, select the
// appropriate neighbour entry. // appropriate neighbour entry.
// //
if (mBootPicker.Hdr.Obj.OffsetX + mBootPicker.SelectedEntry->Hdr.Obj.OffsetX < (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * Context->Scale) { SelectedEntry = InternalGetVolumeEntry (mBootPicker.SelectedIndex);
if (mBootPicker.Hdr.Obj.OffsetX + SelectedEntry->Hdr.Obj.OffsetX < (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * Context->Scale) {
// //
// The internal design ensures a selected entry cannot be off-screen, // The internal design ensures a selected entry cannot be off-screen,
// scrolling offsets it by at most one spot. // scrolling offsets it by at most one spot.
// //
NextEntry = GetNextNode ( if (mBootPicker.SelectedIndex + 1 < mBootPicker.Hdr.Obj.NumChildren) {
&mBootPicker.Hdr.Obj.Children,
&mBootPicker.SelectedEntry->Hdr.Link
);
if (!IsNull(&mBootPicker.Hdr.Obj.Children, NextEntry)) {
InternalBootPickerSelectEntry ( InternalBootPickerSelectEntry (
&mBootPicker, &mBootPicker,
DrawContext, DrawContext,
BASE_CR (NextEntry, GUI_VOLUME_ENTRY, Hdr.Link) mBootPicker.SelectedIndex + 1
); );
} }
ASSERT (!(mBootPicker.Hdr.Obj.OffsetX + mBootPicker.SelectedEntry->Hdr.Obj.OffsetX < (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * Context->Scale)); SelectedEntry = InternalGetVolumeEntry (mBootPicker.SelectedIndex);
ASSERT (!(mBootPicker.Hdr.Obj.OffsetX + SelectedEntry->Hdr.Obj.OffsetX < (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * Context->Scale));
} }
// //
// Scroll the boot entry view by one spot. // Scroll the boot entry view by one spot.
...@@ -1119,7 +1123,7 @@ InternalBootPickerSimpleButtonDraw ( ...@@ -1119,7 +1123,7 @@ InternalBootPickerSimpleButtonDraw (
// //
// There should be no children. // There should be no children.
// //
ASSERT (IsListEmpty (&This->Children)); ASSERT (This->NumChildren == 0);
} }
GUI_OBJ * GUI_OBJ *
...@@ -1228,56 +1232,58 @@ InternalBootPickerRestartPtrEvent ( ...@@ -1228,56 +1232,58 @@ InternalBootPickerRestartPtrEvent (
GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerSelector = { GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerSelector = {
{ {
INITIALIZE_LIST_HEAD_VARIABLE (mBootPicker.Hdr.Obj.Children),
&mBootPicker.Hdr.Obj, &mBootPicker.Hdr.Obj,
{ {
0, 0, 0, 0, 0, 0, 0, 0,
InternalBootPickerSelectorDraw, InternalBootPickerSelectorDraw,
InternalBootPickerSelectorPtrEvent, InternalBootPickerSelectorPtrEvent,
NULL, NULL,
INITIALIZE_LIST_HEAD_VARIABLE (mBootPickerSelector.Hdr.Obj.Children) 0,
NULL
} }
}, },
NULL NULL
}; };
STATIC GUI_OBJ_CHILD *mBootPickerContainerChilds[] = { &mBootPicker.Hdr };
GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CHILD mBootPickerContainer = { GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CHILD mBootPickerContainer = {
{ &mBootPickerLeftScroll.Hdr.Link, &mBootPickerRightScroll.Hdr.Link },
&mBootPickerView, &mBootPickerView,
{ {
0, 0, 0, 0, 0, 0, 0, 0,
GuiObjDrawDelegate, GuiObjDrawDelegate,
GuiObjDelegatePtrEvent, GuiObjDelegatePtrEvent,
NULL, NULL,
INITIALIZE_LIST_HEAD_VARIABLE (mBootPicker.Hdr.Link) ARRAY_SIZE (mBootPickerContainerChilds),
mBootPickerContainerChilds
} }
}; };
GLOBAL_REMOVE_IF_UNREFERENCED GUI_VOLUME_PICKER mBootPicker = { GLOBAL_REMOVE_IF_UNREFERENCED GUI_VOLUME_PICKER mBootPicker = {
{ {
INITIALIZE_LIST_HEAD_VARIABLE (mBootPickerContainer.Obj.Children),
&mBootPickerContainer.Obj, &mBootPickerContainer.Obj,
{ {
0, 0, 0, 0, 0, 0, 0, 0,
GuiObjDrawDelegate, GuiObjDrawDelegate,
GuiObjDelegatePtrEvent, GuiObjDelegatePtrEvent,
InternalBootPickerKeyEvent, InternalBootPickerKeyEvent,
INITIALIZE_LIST_HEAD_VARIABLE (mBootPickerSelector.Hdr.Link) 0,
NULL
} }
}, },
NULL 1
}; };
GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerLeftScroll = { GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerLeftScroll = {
{ {
{ &mBootPickerView.Children, &mBootPickerContainer.Link },
&mBootPickerView, &mBootPickerView,
{ {
0, 0, 0, 0, 0, 0, 0, 0,
InternalBootPickerLeftScrollDraw, InternalBootPickerLeftScrollDraw,
InternalBootPickerLeftScrollPtrEvent, InternalBootPickerLeftScrollPtrEvent,
NULL, NULL,
INITIALIZE_LIST_HEAD_VARIABLE (mBootPickerLeftScroll.Hdr.Obj.Children) 0,
NULL
} }
}, },
NULL NULL
...@@ -1285,14 +1291,14 @@ GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerLeftScroll = { ...@@ -1285,14 +1291,14 @@ GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerLeftScroll = {
GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerRightScroll = { GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerRightScroll = {
{ {
{ &mBootPickerContainer.Link, &mBootPickerActionButtonsContainer.Link },
&mBootPickerView, &mBootPickerView,
{ {
0, 0, 0, 0, 0, 0, 0, 0,
InternalBootPickerRightScrollDraw, InternalBootPickerRightScrollDraw,
InternalBootPickerRightScrollPtrEvent, InternalBootPickerRightScrollPtrEvent,
NULL, NULL,
INITIALIZE_LIST_HEAD_VARIABLE (mBootPickerRightScroll.Hdr.Obj.Children) 0,
NULL
} }
}, },
NULL NULL
...@@ -1300,14 +1306,14 @@ GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerRightScroll = { ...@@ -1300,14 +1306,14 @@ GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerRightScroll = {
GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerRestart = { GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerRestart = {
{ {
{ &mBootPickerActionButtonsContainer.Obj.Children, &mBootPickerShutDown.Hdr.Link },
&mBootPickerActionButtonsContainer.Obj, &mBootPickerActionButtonsContainer.Obj,
{ {
0, 0, 0, 0, 0, 0, 0, 0,
InternalBootPickerSimpleButtonDraw, InternalBootPickerSimpleButtonDraw,
InternalBootPickerRestartPtrEvent, InternalBootPickerRestartPtrEvent,
NULL, NULL,
INITIALIZE_LIST_HEAD_VARIABLE (mBootPickerRestart.Hdr.Obj.Children) 0,
NULL
} }
}, },
NULL NULL
...@@ -1315,37 +1321,50 @@ GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerRestart = { ...@@ -1315,37 +1321,50 @@ GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerRestart = {
GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerShutDown = { GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CLICKABLE mBootPickerShutDown = {
{ {
{ &mBootPickerRestart.Hdr.Link, &mBootPickerActionButtonsContainer.Obj.Children },
&mBootPickerActionButtonsContainer.Obj, &mBootPickerActionButtonsContainer.Obj,
{ {
0, 0, 0, 0, 0, 0, 0, 0,
InternalBootPickerSimpleButtonDraw, InternalBootPickerSimpleButtonDraw,
InternalBootPickerShutDownPtrEvent, InternalBootPickerShutDownPtrEvent,
NULL, NULL,
INITIALIZE_LIST_HEAD_VARIABLE (mBootPickerShutDown.Hdr.Obj.Children) 0,
NULL
} }
}, },
NULL NULL
}; };
STATIC GUI_OBJ_CHILD *mBootPickerActionButtonsContainerChilds[] = {
&mBootPickerRestart.Hdr,
&mBootPickerShutDown.Hdr
};
GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CHILD mBootPickerActionButtonsContainer = { GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ_CHILD mBootPickerActionButtonsContainer = {
{ &mBootPickerRightScroll.Hdr.Link, &mBootPickerView.Children },
&mBootPickerView, &mBootPickerView,
{ {
0, 0, 0, 0, 0, 0, 0, 0,
GuiObjDrawDelegate, GuiObjDrawDelegate,
GuiObjDelegatePtrEvent, GuiObjDelegatePtrEvent,
NULL, NULL,
{ &mBootPickerShutDown.Hdr.Link, &mBootPickerRestart.Hdr.Link } ARRAY_SIZE (mBootPickerActionButtonsContainerChilds),
mBootPickerActionButtonsContainerChilds
} }
}; };
STATIC GUI_OBJ_CHILD *mBootPickerViewChilds[] = {
&mBootPickerContainer,
&mBootPickerActionButtonsContainer,
&mBootPickerLeftScroll.Hdr,
&mBootPickerRightScroll.Hdr
};
GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ mBootPickerView = { GLOBAL_REMOVE_IF_UNREFERENCED GUI_OBJ mBootPickerView = {
0, 0, 0, 0, 0, 0, 0, 0,
InternalBootPickerViewDraw, InternalBootPickerViewDraw,
GuiObjDelegatePtrEvent, GuiObjDelegatePtrEvent,
InternalBootPickerViewKeyEvent, InternalBootPickerViewKeyEvent,
{ &mBootPickerActionButtonsContainer.Link, &mBootPickerLeftScroll.Hdr.Link } ARRAY_SIZE (mBootPickerViewChilds),
mBootPickerViewChilds
}; };
STATIC STATIC
...@@ -1370,17 +1389,17 @@ CopyLabel ( ...@@ -1370,17 +1389,17 @@ CopyLabel (
} }
EFI_STATUS EFI_STATUS
BootPickerEntriesAdd ( BootPickerEntriesSet (
IN OC_PICKER_CONTEXT *Context, IN OC_PICKER_CONTEXT *Context,
IN BOOT_PICKER_GUI_CONTEXT *GuiContext, IN BOOT_PICKER_GUI_CONTEXT *GuiContext,
IN OC_BOOT_ENTRY *Entry, IN OC_BOOT_ENTRY *Entry,
IN UINT8 EntryIndex,
IN BOOLEAN Default IN BOOLEAN Default
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
GUI_VOLUME_ENTRY *VolumeEntry; GUI_VOLUME_ENTRY *VolumeEntry;
CONST GUI_IMAGE *SuggestedIcon; CONST GUI_IMAGE *SuggestedIcon;
LIST_ENTRY *ListEntry;
CONST GUI_VOLUME_ENTRY *PrevEntry; CONST GUI_VOLUME_ENTRY *PrevEntry;
UINT32 IconFileSize; UINT32 IconFileSize;
UINT32 IconTypeIndex; UINT32 IconTypeIndex;
...@@ -1392,6 +1411,8 @@ BootPickerEntriesAdd ( ...@@ -1392,6 +1411,8 @@ BootPickerEntriesAdd (
ASSERT (GuiContext != NULL); ASSERT (GuiContext != NULL);
ASSERT (Entry != NULL); ASSERT (Entry != NULL);
ASSERT (EntryIndex > 0);
ASSERT (EntryIndex < mBootPicker.Hdr.Obj.NumChildren);
DEBUG ((DEBUG_INFO, "OCUI: Console attributes: %d\n", Context->ConsoleAttributes)); DEBUG ((DEBUG_INFO, "OCUI: Console attributes: %d\n", Context->ConsoleAttributes));
...@@ -1578,27 +1599,23 @@ BootPickerEntriesAdd ( ...@@ -1578,27 +1599,23 @@ BootPickerEntriesAdd (
VolumeEntry->Hdr.Obj.Height = BOOT_ENTRY_HEIGHT * GuiContext->Scale; VolumeEntry->Hdr.Obj.Height = BOOT_ENTRY_HEIGHT * GuiContext->Scale;
VolumeEntry->Hdr.Obj.Draw = InternalBootPickerEntryDraw; VolumeEntry->Hdr.Obj.Draw = InternalBootPickerEntryDraw;
VolumeEntry->Hdr.Obj.PtrEvent = InternalBootPickerEntryPtrEvent; VolumeEntry->Hdr.Obj.PtrEvent = InternalBootPickerEntryPtrEvent;
InitializeListHead (&VolumeEntry->Hdr.Obj.Children); VolumeEntry->Hdr.Obj.NumChildren = 0;
VolumeEntry->Hdr.Obj.Children = NULL;
// //
// The last entry is always the selector. // The first entry is always the selector.
// //
ListEntry = mBootPicker.Hdr.Obj.Children.BackLink; if (EntryIndex > 1) {
ASSERT (ListEntry == &mBootPickerSelector.Hdr.Link); PrevEntry = InternalGetVolumeEntry (EntryIndex - 1);
ListEntry = ListEntry->BackLink;
ASSERT (ListEntry != NULL);
if (!IsNull (&mBootPicker.Hdr.Obj.Children, ListEntry)) {
PrevEntry = BASE_CR (ListEntry, GUI_VOLUME_ENTRY, Hdr.Link);
VolumeEntry->Hdr.Obj.OffsetX = PrevEntry->Hdr.Obj.OffsetX + (BOOT_ENTRY_DIMENSION + BOOT_ENTRY_SPACE) * GuiContext->Scale; VolumeEntry->Hdr.Obj.OffsetX = PrevEntry->Hdr.Obj.OffsetX + (BOOT_ENTRY_DIMENSION + BOOT_ENTRY_SPACE) * GuiContext->Scale;
} }
InsertHeadList (ListEntry, &VolumeEntry->Hdr.Link); mBootPicker.Hdr.Obj.Children[EntryIndex] = &VolumeEntry->Hdr;
VolumeEntry->Index = EntryIndex;
mBootPicker.Hdr.Obj.Width += (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * GuiContext->Scale; mBootPicker.Hdr.Obj.Width += (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * GuiContext->Scale;
mBootPicker.Hdr.Obj.OffsetX -= (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * GuiContext->Scale / 2; mBootPicker.Hdr.Obj.OffsetX -= (BOOT_ENTRY_WIDTH + BOOT_ENTRY_SPACE) * GuiContext->Scale / 2;
if (Default) { if (Default) {
InternalBootPickerSelectEntry (&mBootPicker, NULL, VolumeEntry); InternalBootPickerSelectEntry (&mBootPicker, NULL, VolumeEntry->Index);
GuiContext->BootEntry = Entry; GuiContext->BootEntry = Entry;
} }
...@@ -1764,7 +1781,8 @@ EFI_STATUS ...@@ -1764,7 +1781,8 @@ EFI_STATUS
BootPickerViewInitialize ( BootPickerViewInitialize (
OUT GUI_DRAWING_CONTEXT *DrawContext, OUT GUI_DRAWING_CONTEXT *DrawContext,
IN BOOT_PICKER_GUI_CONTEXT *GuiContext, IN BOOT_PICKER_GUI_CONTEXT *GuiContext,
IN GUI_CURSOR_GET_IMAGE GetCursorImage IN GUI_CURSOR_GET_IMAGE GetCursorImage,
IN UINT8 NumBootEntries
) )
{ {
UINT32 ContainerMaxWidth; UINT32 ContainerMaxWidth;
...@@ -1840,7 +1858,14 @@ BootPickerViewInitialize ( ...@@ -1840,7 +1858,14 @@ BootPickerViewInitialize (
mBootPicker.Hdr.Obj.OffsetX = mBootPickerContainer.Obj.Width / 2 + (UINT32) (BOOT_ENTRY_SPACE * GuiContext->Scale) / 2; mBootPicker.Hdr.Obj.OffsetX = mBootPickerContainer.Obj.Width / 2 + (UINT32) (BOOT_ENTRY_SPACE * GuiContext->Scale) / 2;
mBootPicker.Hdr.Obj.OffsetY = 0; mBootPicker.Hdr.Obj.OffsetY = 0;
mBootPicker.SelectedEntry = NULL; mBootPicker.SelectedIndex = 1;
mBootPicker.Hdr.Obj.Children = AllocateZeroPool ((NumBootEntries + 1) * sizeof (*mBootPicker.Hdr.Obj.Children));
if (mBootPicker.Hdr.Obj.Children == NULL) {
return EFI_OUT_OF_RESOURCES;
}
mBootPicker.Hdr.Obj.Children[0] = &mBootPickerSelector.Hdr;
mBootPicker.Hdr.Obj.NumChildren = NumBootEntries + 1;
mBootPickerRestart.CurrentImage = &GuiContext->Icons[ICON_RESTART][ICON_TYPE_BASE]; mBootPickerRestart.CurrentImage = &GuiContext->Icons[ICON_RESTART][ICON_TYPE_BASE];
mBootPickerRestart.Hdr.Obj.Width = mBootPickerRestart.CurrentImage->Width; mBootPickerRestart.Hdr.Obj.Width = mBootPickerRestart.CurrentImage->Width;
...@@ -1894,12 +1919,10 @@ BootPickerViewLateInitialize ( ...@@ -1894,12 +1919,10 @@ BootPickerViewLateInitialize (
VOID VOID
) )
{ {
UINT32 Index;
INT64 ScrollOffset; INT64 ScrollOffset;
CONST LIST_ENTRY *ListEntry;
CONST GUI_VOLUME_ENTRY *BootEntry; CONST GUI_VOLUME_ENTRY *BootEntry;
ASSERT (mBootPicker.SelectedEntry != NULL);
ScrollOffset = InternelBootPickerScrollSelected (); ScrollOffset = InternelBootPickerScrollSelected ();
// //
// If ScrollOffset is non-0, the selected entry will be aligned left- or // If ScrollOffset is non-0, the selected entry will be aligned left- or
...@@ -1909,19 +1932,14 @@ BootPickerViewLateInitialize ( ...@@ -1909,19 +1932,14 @@ BootPickerViewLateInitialize (
if (ScrollOffset == 0) { if (ScrollOffset == 0) {
// //
// Find the first entry that is fully visible. // Find the first entry that is fully visible.
// Last entry is always the selector. // First entry is always the selector.
// //
ASSERT (mBootPicker.Hdr.Obj.Children.BackLink == &mBootPickerSelector.Hdr.Link); for (Index = 1; Index < mBootPicker.Hdr.Obj.NumChildren; ++Index) {
for (
ListEntry = GetFirstNode (&mBootPicker.Hdr.Obj.Children);
ListEntry != mBootPicker.Hdr.Obj.Children.BackLink;
ListEntry = GetNextNode (&mBootPicker.Hdr.Obj.Children, ListEntry)
) {
// //
// Move the first partially visible boot entry to the very left to prevent // Move the first partially visible boot entry to the very left to prevent
// cut-off entries. This only applies when entries overflow. // cut-off entries. This only applies when entries overflow.
// //
BootEntry = BASE_CR (ListEntry, GUI_VOLUME_ENTRY, Hdr.Link); BootEntry = InternalGetVolumeEntry (Index);
if (mBootPicker.Hdr.Obj.OffsetX + BootEntry->Hdr.Obj.OffsetX >= 0) { if (mBootPicker.Hdr.Obj.OffsetX + BootEntry->Hdr.Obj.OffsetX >= 0) {
// //
// Move the cut-off entry on-screen. // Move the cut-off entry on-screen.
...@@ -1932,13 +1950,6 @@ BootPickerViewLateInitialize ( ...@@ -1932,13 +1950,6 @@ BootPickerViewLateInitialize (
ScrollOffset = mBootPicker.Hdr.Obj.OffsetX + BootEntry->Hdr.Obj.OffsetX; ScrollOffset = mBootPicker.Hdr.Obj.OffsetX + BootEntry->Hdr.Obj.OffsetX;
} }
if (mBootPicker.Hdr.Obj.Children.BackLink != mBootPicker.Hdr.Obj.Children.ForwardLink) {
//
// mBootPicker must not be entirely off-screen.
//
ASSERT (ListEntry != mBootPicker.Hdr.Obj.Children.BackLink);
}
} }
mBootPicker.Hdr.Obj.OffsetX += ScrollOffset; mBootPicker.Hdr.Obj.OffsetX += ScrollOffset;
...@@ -1950,27 +1961,20 @@ BootPickerViewDeinitialize ( ...@@ -1950,27 +1961,20 @@ BootPickerViewDeinitialize (
IN OUT BOOT_PICKER_GUI_CONTEXT *GuiContext IN OUT BOOT_PICKER_GUI_CONTEXT *GuiContext
) )
{ {
LIST_ENTRY *ListEntry; UINT32 Index;
LIST_ENTRY *NextEntry;
GUI_VOLUME_ENTRY *BootEntry;
ListEntry = mBootPicker.Hdr.Obj.Children.BackLink;
ASSERT (ListEntry == &mBootPickerSelector.Hdr.Link);
ASSERT (mBootPicker.Hdr.Obj.Children[0] == &mBootPickerSelector.Hdr);
// //
// Last entry is always the selector, which is special and cannot be freed. // Last entry is always the selector, which is special and cannot be freed.
// //
ListEntry = ListEntry->BackLink; for (Index = 1; Index < mBootPicker.Hdr.Obj.NumChildren; ++Index) {
InternalBootPickerEntryDestruct (InternalGetVolumeEntry (Index));
while (!IsNull (&mBootPicker.Hdr.Obj.Children, ListEntry)) { }
NextEntry = ListEntry->BackLink;
RemoveEntryList (ListEntry);
BootEntry = BASE_CR (ListEntry, GUI_VOLUME_ENTRY, Hdr.Link);
InternalBootPickerEntryDestruct (BootEntry);
ListEntry = NextEntry; if (mBootPicker.Hdr.Obj.Children != NULL) {
FreePool (mBootPicker.Hdr.Obj.Children);
} }
mBootPicker.Hdr.Obj.NumChildren = 0;
GuiViewDeinitialize (DrawContext, GuiContext); GuiViewDeinitialize (DrawContext, GuiContext);
} }
...@@ -21,11 +21,12 @@ typedef struct { ...@@ -21,11 +21,12 @@ typedef struct {
GUI_IMAGE Label; GUI_IMAGE Label;
OC_BOOT_ENTRY *Context; OC_BOOT_ENTRY *Context;
BOOLEAN CustomIcon; BOOLEAN CustomIcon;
UINT8 Index;
} GUI_VOLUME_ENTRY; } GUI_VOLUME_ENTRY;
typedef struct { typedef struct {
GUI_OBJ_CHILD Hdr; GUI_OBJ_CHILD Hdr;
GUI_VOLUME_ENTRY *SelectedEntry; UINT32 SelectedIndex;
} GUI_VOLUME_PICKER; } GUI_VOLUME_PICKER;
#endif // BOOT_PICKER_H #endif // BOOT_PICKER_H
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册