VOID Ctor()

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;
}