alder_lake_bios/Insyde/InsydeSetupPkg/Drivers/H2ODisplayEngineLocalMetroDxe/UiLib/UiLabel.c

530 lines
14 KiB
C

/** @file
UI Common Controls
;******************************************************************************
;* Copyright (c) 2012 - 2020, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "UiControls.h"
#include <Library/UefiLib.h>
STATIC UI_LABEL_CLASS *mLabelClass = NULL;
#define CURRENT_CLASS mLabelClass
#define MARQUEE_TIMER_ID 2
#define MARQUEE_TIMER_INTERVAL 150
EFI_STATUS
UiLabelMarquee (
IN UI_CONTROL *Control
)
{
UI_LABEL *Label;
SIZE Size;
RECT Rect;
UINTN StrWidth;
UINTN ControlWidth;
CHAR16 *SingleLineText;
CHAR16 *Char;
CHAR16 *Text;
CHAR16 *Tail;
CHAR16 *Result;
CHAR16 BlankStr[] = L" ";
if (Control == NULL) {
return EFI_INVALID_PARAMETER;
}
Label = (UI_LABEL *)Control;
if (!Label->Marquee) {
Label->MarqueeOffset = 0;
return EFI_UNSUPPORTED;
}
if (Label->Text == NULL) {
return EFI_UNSUPPORTED;
}
if ((Label->TextStyle & DT_SINGLELINE) == 0) {
return EFI_UNSUPPORTED;
}
Control->Manager->GetControlRect (Control->Manager, Control, &Rect);
Rect.left += GetControlPaddingLeft (Control);
Rect.top += GetControlPaddingTop (Control);
Rect.right -= GetControlPaddingRight (Control);
Rect.bottom -= GetControlPaddingBottom (Control);
ControlWidth = (UINTN)(Rect.right - Rect.left);
Control->Manager->PaintDC->font->FontSize = GetControlFontSize (Control);
SingleLineText = CatSPrint (NULL, L"%s", Label->Text);
if (SingleLineText == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Char = SingleLineText;
while (*Char != '\0') {
if (*Char == '\n' || *Char == '\r') {
*Char = ' ';
}
Char ++;
}
GetTextExtentPoint32 (Control->Manager->PaintDC, SingleLineText, (int)StrLen (SingleLineText), &Size);
StrWidth = (UINTN)Size.cx;
if (StrWidth == 0 || ControlWidth == 0 || StrWidth <= ControlWidth) {
FreePool (SingleLineText);
return EFI_UNSUPPORTED;
}
Text = CatSPrint (NULL, L"%s%s", SingleLineText, BlankStr);
FreePool (SingleLineText);
if (Text == NULL) {
return EFI_OUT_OF_RESOURCES;
}
if (Label->MarqueeOffset < StrLen (Text) - 2) {
Label->MarqueeOffset ++;
} else {
Label->MarqueeOffset = 1;
}
Tail = CatSPrint (NULL, L"%s", Text);
if (Tail == NULL) {
FreePool (Text);
return EFI_OUT_OF_RESOURCES;
}
Tail[Label->MarqueeOffset] = L'\0';
Result = CatSPrint (NULL, L"%s%s", Text + Label->MarqueeOffset, Tail);
FreePool (Text);
FreePool (Tail);
if (Result == NULL) {
return EFI_OUT_OF_RESOURCES;
}
if (Label->MarqueeText != NULL) {
FreePool (Label->MarqueeText);
}
Label->MarqueeText = Result;
CONTROL_CLASS_INVALIDATE (Control);
return EFI_SUCCESS;
}
SIZE
EFIAPI
UiLabelEstimateSize (
UI_CONTROL *Control,
SIZE AvailableSize
)
{
RECT TextRc;
UI_LABEL *This;
SIZE Size;
INT32 TextWidth;
UINT32 TextStyle;
This = (UI_LABEL *) Control;
if (This->Text[0] == '\0') {
switch ((INTN) Control->Width.Type) {
case (INTN) UI_LENGTH_TYPE_MATCH_PARENT:
Size.cx = AvailableSize.cx - (GetControlPaddingWidth (Control) + GetControlBorderWidth (Control));
break;
case (INTN) UI_LENGTH_TYPE_WRAP_CONTENT:
Size.cx = 1;
break;
case UI_LENGTH_TYPE_UNDEFINED:
default:
Size.cx = CalculateControlDisplayWidth (Control, AvailableSize);
break;
}
switch ((INTN) Control->Height.Type) {
case (INTN) UI_LENGTH_TYPE_MATCH_PARENT:
Size.cy = AvailableSize.cy - (GetControlPaddingHeight (Control) + GetControlBorderHeight (Control));
break;
case (INTN) UI_LENGTH_TYPE_WRAP_CONTENT:
Size.cy = GetControlFontSize (Control);
break;
case UI_LENGTH_TYPE_UNDEFINED:
default:
Size.cy = CalculateControlDisplayHeight (Control, AvailableSize);
break;
}
return Size;
}
switch ((INTN) Control->Height.Type) {
case (INTN) UI_LENGTH_TYPE_WRAP_CONTENT:
switch ((INTN) Control->Width.Type) {
case (INTN) UI_LENGTH_TYPE_MATCH_PARENT:
TextWidth = AvailableSize.cx - (GetControlPaddingWidth (Control) + GetControlBorderWidth (Control));
break;
case (INTN) UI_LENGTH_TYPE_WRAP_CONTENT:
//
// BUGBUG: not yet implement
//
ASSERT (FALSE);
TextWidth = AvailableSize.cx;
break;
default:
if (!IS_CONTROL_WIDTH_VALUE_ASSIGNED (Control)) {
Size.cx = 0;
Size.cy = GetControlFontSize (Control);
return Size;
}
TextWidth = CalculateControlDisplayWidth (Control, AvailableSize) - (GetControlPaddingWidth (Control) + GetControlBorderWidth (Control));
break;
}
ASSERT (TextWidth >= 0);
SetRect (&TextRc, 0, 0, TextWidth, 9999);
TextStyle = This->TextStyle;
if ((TextStyle & DT_SINGLELINE) == 0) {
TextStyle |= DT_WORDBREAK;
}
if (This->ShowHtmlText) {
TextStyle |= DT_HTML_TEXT;
}
UiPaintText (
Control->Manager->PaintDC,
GetControlFontSize (Control),
&TextRc,
This->Text,
Control->TextColor,
INVALID_COLOR,
TextStyle | DT_CALCRECT
);
Size.cx = CalculateControlDisplayWidth (Control, AvailableSize);
Size.cy = MAX (TextRc.bottom - TextRc.top + GetControlPaddingHeight (Control) + GetControlBorderHeight (Control), Control->MinSize.cy);
Size.cy = MAX (Size.cy, 0);
break;
case (INTN) UI_LENGTH_TYPE_MATCH_PARENT:
Size.cx = CalculateControlDisplayWidth (Control, AvailableSize);
Size.cy = AvailableSize.cy;
switch ((INTN) Control->Width.Type) {
case (INTN) UI_LENGTH_TYPE_MATCH_PARENT:
Size.cx = AvailableSize.cx;
break;
}
break;
case UI_LENGTH_TYPE_UNDEFINED:
default:
Size = CalculateControlDisplaySize (Control, AvailableSize);
switch ((INTN) Control->Width.Type) {
case (INTN) UI_LENGTH_TYPE_MATCH_PARENT:
Size.cx = AvailableSize.cx;
break;
case (INTN) UI_LENGTH_TYPE_WRAP_CONTENT:
SetRect (&TextRc, 0, 0, 99999, 99999);
TextStyle = This->TextStyle;
if (This->ShowHtmlText) {
TextStyle |= DT_HTML_TEXT;
}
UiPaintText (
Control->Manager->PaintDC,
GetControlFontSize (Control),
&TextRc,
This->Text,
Control->TextColor,
INVALID_COLOR,
TextStyle | DT_CALCRECT
);
Size.cx = MAX (TextRc.right - TextRc.left + GetControlPaddingWidth (Control) + GetControlBorderWidth (Control), Control->MinSize.cx);
Size.cx = MAX (Size.cx, 0);
break;
}
break;
}
Size.cx = MAX (Size.cx, Control->MinSize.cx);
if (Control->MaxSize.cx > 0) {
Size.cx = MIN (Size.cx, Control->MaxSize.cx);
}
return Size;
}
BOOLEAN
EFIAPI
UiLabelSetAttribute (
UI_CONTROL *Control,
CHAR16 *Name,
CHAR16 *Value
)
{
UI_LABEL *This;
CHAR16 *Delim;
This = (UI_LABEL *) Control;
if (StrCmp (Name, L"text") == 0) {
FreePool (This->Text);
This->Text = StrDuplicate (Value);
} else if (StrCmp (Name, L"focustextcolor") == 0) {
This->FocusTextColor = GetColorValue (Value);
} else if (StrCmp (Name, L"text-align") == 0) {
do {
if (StrnCmp (Value, L"bottom", 6) == 0) {
This->TextStyle &= ~(DT_TOP | DT_VCENTER | DT_LEFT | DT_RIGHT | DT_CENTER);
This->TextStyle |= DT_CENTER | DT_BOTTOM | DT_SINGLELINE;
} else if (StrnCmp (Value, L"center", 6) == 0) {
This->TextStyle &= ~(DT_LEFT | DT_RIGHT);
This->TextStyle |= DT_CENTER;
} else if (StrnCmp (Value, L"singleline", 10) == 0) {
This->TextStyle |= DT_SINGLELINE;
} else if (StrnCmp (Value, L"right", 5) == 0) {
This->TextStyle |= DT_RIGHT;
} else if (StrnCmp (Value, L"left", 4) == 0) {
This->TextStyle |= DT_LEFT;
} else {
DEBUG ((EFI_D_ERROR, "Unsuppoerted align type:%s", Value));
ASSERT (!L"Unsupported align type");
}
Delim = StrStr (Value, L"|");
if (Delim == NULL) {
break;
} else {
Value = Delim + 1;
}
} while (*Value != L'\0');
} else if (StrCmp (Name, L"text-overflow") == 0) {
if (StrnCmp (Value, L"ellipsis", 8) == 0) {
This->TextStyle |= DT_END_ELLIPSIS;
This->Ellipsis = TRUE;
} else if (StrCmp (Value, L"") == 0) {
This->TextStyle &= ~(DT_END_ELLIPSIS);
This->Ellipsis = FALSE;
} else {
DEBUG ((EFI_D_ERROR, "Unsuppoerted text-overflow type:%s", Value));
ASSERT (!L"Unsupported align type");
}
} else if (StrCmp (Name, L"marquee") == 0) {
if (StrCmp (Value, L"true") == 0) {
This->Marquee = TRUE;
SetTimer (Control->Wnd, MARQUEE_TIMER_ID, MARQUEE_TIMER_INTERVAL, NULL);
if (This->Ellipsis && (This->TextStyle & DT_SINGLELINE) != 0) {
This->TextStyle &= ~(DT_END_ELLIPSIS);
}
} else {
This->Marquee = FALSE;
This->MarqueeOffset = 0;
if (This->MarqueeText != NULL) {
FreePool (This->MarqueeText);
This->MarqueeText = NULL;
}
KillTimer (Control->Wnd, MARQUEE_TIMER_ID);
if (This->Ellipsis) {
This->TextStyle |= DT_END_ELLIPSIS;
}
}
} else if (StrCmp (Name, L"show_html_text") == 0) {
if (StrCmp (Value, L"true") == 0) {
This->ShowHtmlText = TRUE;
} else if (StrCmp (Value, L"false") == 0) {
This->ShowHtmlText = FALSE;
} else {
ASSERT (FALSE);
}
} else {
return PARENT_CLASS_SET_ATTRIBUTE (CURRENT_CLASS, Control, Name, Value);
}
CONTROL_CLASS_INVALIDATE (This);
return TRUE;
}
LRESULT
EFIAPI
UiLabelProc (
HWND Hwnd,
UINT32 Msg,
WPARAM WParam,
LPARAM LParam
)
{
UI_CONTROL *Control;
UI_LABEL *This;
UINT32 TextColor;
RECT Rect;
HDC Hdc;
UI_MANAGER *Manager;
UINT32 TextStyle;
CHAR16 *Text;
Control = (UI_CONTROL *) GetWindowLongPtr (Hwnd, 0);
if (Control == NULL && Msg != WM_CREATE && Msg != WM_NCCALCSIZE) {
ASSERT (FALSE);
return 0;
}
This = (UI_LABEL *) Control;
Manager = NULL;
if (This != NULL) {
Manager = This->Control.Manager;
}
switch (Msg) {
case WM_CREATE:
This = (UI_LABEL *) AllocateZeroPool (sizeof (UI_LABEL));
if (This != NULL) {
CONTROL_CLASS (This) = (UI_CONTROL_CLASS *) GetClassLongPtr (Hwnd, 0);
SetWindowLongPtr (Hwnd, 0, (INTN)This);
SendMessage (Hwnd, UI_NOTIFY_CREATE, WParam, LParam);
}
break;
case UI_NOTIFY_CREATE:
PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, UI_NOTIFY_CREATE, WParam, LParam);
This->TextStyle = DT_VCENTER;
This->Text = StrDuplicate (L"");
This->ShowHtmlText = FALSE;
if (PcdGet32(PcdH2OLmdeMultiLayout) == 0) {
This->TextStyle |= DT_END_ELLIPSIS;
This->Ellipsis = TRUE;
}
break;
case WM_TIMER:
PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
if (WParam == MARQUEE_TIMER_ID) {
UiLabelMarquee (Control);
}
break;
case UI_NOTIFY_PAINT:
if (WParam == PAINT_TEXT) {
Hdc = Manager->PaintDC;
Manager->GetControlRect (Manager, (UI_CONTROL *)This, &Rect);
TextColor = Control->TextColor;
if ((CONTROL_CLASS_GET_STATE(Control) & UISTATE_FOCUSED) != 0 && This->FocusTextColor != 0) {
TextColor = This->FocusTextColor;
}
if (TextColor == 0) {
TextColor = 0xFF000000;
}
Rect.left += (GetControlPaddingLeft (Control) + GetControlBorderLeft (Control) );
Rect.top += (GetControlPaddingTop (Control) + GetControlBorderTop (Control) );
Rect.right -= (GetControlPaddingRight (Control) + GetControlBorderRight (Control) );
Rect.bottom -= (GetControlPaddingBottom (Control) + GetControlBorderBottom (Control));
Control->Manager->PaintDC->font->FontSize = GetControlFontSize (Control);
TextStyle = This->TextStyle;
if ((TextStyle & DT_SINGLELINE) == 0) {
TextStyle |= DT_WORDBREAK;
}
if (This->ShowHtmlText) {
TextStyle |= DT_HTML_TEXT;
}
if (This->Marquee && This->MarqueeText != NULL) {
Text = This->MarqueeText;
} else {
Text = This->Text;
}
UiPaintText (
Control->Manager->PaintDC,
GetControlFontSize (Control),
&Rect,
Text,
TextColor,
INVALID_COLOR,
TextStyle
);
} else {
PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
}
break;
case WM_NCHITTEST:
return HTTRANSPARENT;
case WM_DESTROY:
if (This->Text != NULL) {
FreePool (This->Text);
}
if (This->Marquee) {
if (This->MarqueeText != NULL) {
FreePool (This->MarqueeText);
This->MarqueeText = NULL;
}
KillTimer (Control->Wnd, MARQUEE_TIMER_ID);
}
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
default:
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
}
return 0;
}
UI_LABEL_CLASS *
EFIAPI
GetLabelClass (
VOID
)
{
if (CURRENT_CLASS != NULL) {
return CURRENT_CLASS;
}
InitUiClass ((UI_CONTROL_CLASS **)&CURRENT_CLASS, sizeof (*CURRENT_CLASS), L"Label", (UI_CONTROL_CLASS *)GetControlClass());
if (CURRENT_CLASS == NULL) {
return NULL;
}
((UI_CONTROL_CLASS *)CURRENT_CLASS)->WndProc = UiLabelProc;
((UI_CONTROL_CLASS *)CURRENT_CLASS)->SetAttribute = UiLabelSetAttribute;
((UI_CONTROL_CLASS *)CURRENT_CLASS)->EstimateSize = UiLabelEstimateSize;
return CURRENT_CLASS;
}