in MsGraphicsPkg/Library/SimpleUIToolKit/ListBox.c [925:1074]
VOID Ctor(IN ListBox *this,
IN SWM_RECT CellBox,
IN UINT32 Flags,
IN EFI_FONT_INFO *FontInfo,
IN UINT32 CellTextXOffset,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NormalColor,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *HoverColor,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *SelectColor,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *GrayOutColor,
IN UIT_LB_CELLDATA *CellData,
IN VOID *pSelectionContext)
{
UINT32 Index;
SWM_RECT Rect;
UINT32 MaxGlyphDescent;
UINT32 CheckBoxHitAreaWidth = 0;
UINT32 TrashcanHitAreaWidth = 0;
// Initialize variables.
//
this->m_FontInfo = DupFontInfo (FontInfo);
if (NULL == this->m_FontInfo)
{
goto Exit;
}
this->m_NormalColor = *NormalColor;
this->m_HoverColor = *HoverColor;
this->m_SelectColor = *SelectColor;
this->m_GrayOutColor = *GrayOutColor;
this->m_SelectedCell = 0;
this->m_TargetCell = 0;
this->m_LastAction = LB_ACTION_NONE;
this->m_HighlightedCell = UIT_INVALID_SELECTION;
this->m_Flags = Flags;
this->m_pSelectionContext = pSelectionContext;
this->m_State = NORMAL;
// Determine how many listbox entries (cells) and allocate space to store details. At the same time
// calculate the overall control's outer bounds.
//
for (this->m_NumberOfCells = 0 ; CellData[this->m_NumberOfCells].CellText != NULL ; this->m_NumberOfCells++)
{
}
this->m_ListBoxBounds.Left = CellBox.Left;
this->m_ListBoxBounds.Top = CellBox.Top;
this->m_ListBoxBounds.Right = CellBox.Right;
this->m_ListBoxBounds.Bottom = (CellBox.Top + ((CellBox.Bottom - CellBox.Top + 1) * this->m_NumberOfCells));
this->m_pCells = AllocateZeroPool(this->m_NumberOfCells * sizeof(CellDisplayInfo));
ASSERT(NULL != this->m_pCells);
if (NULL == this->m_pCells)
{
goto Exit;
}
// Capture first cell bounding rectangle.
//
CopyMem (&Rect, &CellBox, sizeof(SWM_RECT));
// Iterate through cell list and compute bounding rectangle, checkbox bounding rectangle (optional) and string bitmap rectangle.
//
for (Index = 0; CellData[Index].CellText != NULL && Index < this->m_NumberOfCells; Index++)
{
this->m_pCells[Index].OriginalOrder = Index;
this->m_pCells[Index].pCellText = AllocateCopyPool(StrSize(CellData[Index].CellText), CellData[Index].CellText);
this->m_pCells[Index].CheckboxSelected = CellData[Index].CheckBoxSelected;
this->m_pCells[Index].TrashcanEnabled = CellData[Index].TrashcanEnabled;
CopyMem(&this->m_pCells[Index].CellBounds, &Rect, sizeof(SWM_RECT));
// If this is a checkbox type ListBox, compute the checkbox bounding rectangle.
//
if (UIT_LISTBOX_FLAGS_CHECKBOX == (this->m_Flags & UIT_LISTBOX_FLAGS_CHECKBOX))
{
SWM_RECT *CellBounds = &this->m_pCells[Index].CellBounds;
CopyMem(&this->m_pCells[Index].CellCheckBoxBounds, CellBounds, sizeof(SWM_RECT));
CheckBoxHitAreaWidth = (CellBounds->Bottom - CellBounds->Top + 1);
this->m_pCells[Index].CellCheckBoxBounds.Right = (CellBounds->Left + CheckBoxHitAreaWidth);
}
// If this is a checkbox type ListBox, compute the checkbox bounding rectangle.
//
if (UIT_LISTBOX_FLAGS_ALLOW_DELETE == (this->m_Flags & UIT_LISTBOX_FLAGS_ALLOW_DELETE))
{
SWM_RECT *CellBounds = &this->m_pCells[Index].CellBounds;
CopyMem(&this->m_pCells[Index].CellTrashcanBounds, CellBounds, sizeof(SWM_RECT));
TrashcanHitAreaWidth = (CellBounds->Bottom - CellBounds->Top + 1);
this->m_pCells[Index].CellTrashcanBounds.Left = (CellBounds->Right - TrashcanHitAreaWidth);
}
// Calculate cell text bounding rectangle (cell text should be vertically centered in the cell, accounting for the maximum font glyph descent). Also,
// the text may be indented from the left edge of the cell.
//
CopyMem(&this->m_pCells[Index].CellTextBounds, &Rect, sizeof(SWM_RECT));
// Offset for the checkbox if one exists.
//
this->m_pCells[Index].CellTextBounds.Left += (CheckBoxHitAreaWidth + CellTextXOffset);
this->m_pCells[Index].CellTextBounds.Right -= TrashcanHitAreaWidth;
GetTextStringBitmapSize (CellData[Index].CellText,
FontInfo,
TRUE,
EFI_HII_OUT_FLAG_CLIP |
EFI_HII_OUT_FLAG_CLIP_CLEAN_X | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y |
EFI_HII_IGNORE_LINE_BREAK,
&this->m_pCells[Index].CellTextBounds,
&MaxGlyphDescent
);
UINT32 CellHeight = (this->m_pCells[Index].CellBounds.Bottom - this->m_pCells[Index].CellBounds.Top + 1);
UINT32 StringWidth = (this->m_pCells[Index].CellTextBounds.Right - this->m_pCells[Index].CellTextBounds.Left + 1);
UINT32 StringHeight = (this->m_pCells[Index].CellTextBounds.Bottom - this->m_pCells[Index].CellTextBounds.Top + 1);
this->m_pCells[Index].CellTextBounds.Right = (this->m_pCells[Index].CellTextBounds.Left + StringWidth - 1);
this->m_pCells[Index].CellTextBounds.Top += ((CellHeight / 2) - (StringHeight / 2) + MaxGlyphDescent);
this->m_pCells[Index].CellTextBounds.Bottom = (this->m_pCells[Index].CellTextBounds.Top + StringHeight + MaxGlyphDescent - 1);
// Increment to the next cell position.
//
Rect.Top += (CellBox.Bottom - CellBox.Top + 1);
Rect.Bottom += (CellBox.Bottom - CellBox.Top + 1);
}
// Member Variables
this->Base.ControlType = LISTBOX;
// Functions.
//
this->Base.Draw = (DrawFunctionPtr) &Draw;
this->Base.SetControlBounds = (SetControlBoundsFunctionPtr) &SetControlBounds;
this->Base.GetControlBounds = (GetControlBoundsFunctionPtr) &GetControlBounds;
this->Base.SetControlState = (SetControlStateFunctionPtr) &SetControlState;
this->Base.GetControlState = (GetControlStateFunctionPtr) &GetControlState;
this->Base.CopySettings = (CopySettingsFunctionPtr) &CopySettings;
this->GetSelectedCellIndex = &GetSelectedCellIndex;
Exit:
return;
}