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

440 lines
13 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 "H2ODisplayEngineLocalMetro.h"
#include "MetroUi.h"
STATIC UI_SWITCH_CLASS *mSwitchClass = NULL;
#define CURRENT_CLASS mSwitchClass
#if FixedPcdGet32(PcdH2OLmdeMultiLayout) == 0
CHAR16 *mSwitchChilds = L""
L"<Label float='true' background-image='@CheckBoxBorder' name='CheckboxBorder' scale9grid='14,1,14,1'/>"
L"<Label float='true' padding='3,5,4,5' background-image='@CheckBoxBkg' name='CheckboxBkg' scale9grid='14,1,14,1'/>"
L"<Label textcolor='0xFFFFFFFF' float='true' font-size='17' name='CheckboxText'/>"
L"<HorizontalLayout float='true' name='CheckboxButton'>"
L"<Label background-image='@CheckBoxButton' scale9grid='11,1,11,1'/>"
L"</HorizontalLayout>";
#endif
#define SWITCH_TEXT_LENGTH 60
#define SWITCH_BORDER_WIDTH 4
VOID
UpdateSwitch (
UI_CONTROL *Control,
CONST RECT *Rc
)
{
UI_SWITCH *This;
UI_CONTROL *Child;
CHAR16 Str[20];
INT32 Width;
INT32 Height;
INT32 ThumbWidth;
INT32 ThumbHeight;
INT32 FreeWidth;
This = (UI_SWITCH *) Control;
Width = Rc->right - Rc->left;
Height = Rc->bottom - Rc->top;
ASSERT (Width >= 98 && Height >= 20);
ThumbWidth = (Width - SWITCH_BORDER_WIDTH * 2) / 3;
ThumbHeight = Height - 7;
UnicodeSPrint (Str, sizeof (Str), L"3,%d,4,%d", Width - ThumbWidth - 4 - This->ThumbPos, This->ThumbPos + 4);
Child = UiFindChildByName (Control, L"CheckboxButton");
UiSetAttribute (Child, L"padding", Str);
if (This->ThumbPos < This->ThumbRange / 2) {
Child = UiFindChildByName (Control, L"CheckboxText");
UiSetAttribute (Child, L"text", L"Disabled");
FreeWidth = Width - SWITCH_TEXT_LENGTH - ThumbWidth - SWITCH_BORDER_WIDTH * 2;
UnicodeSPrint (Str, sizeof (Str), L"%d,4,4,%d", (Height - 20) / 2, ThumbWidth + SWITCH_BORDER_WIDTH + FreeWidth / 2);
UiSetAttribute (Child, L"padding", Str);
} else {
Child = UiFindChildByName (Control, L"CheckboxText");
UiSetAttribute (Child, L"text", L"Enabled");
FreeWidth = Width - SWITCH_TEXT_LENGTH - ThumbWidth - SWITCH_BORDER_WIDTH * 2;
UnicodeSPrint (Str, sizeof (Str), L"%d,4,4,%d", (Height - 20) / 2, SWITCH_BORDER_WIDTH + FreeWidth / 2);
UiSetAttribute (Child, L"padding", Str);
}
}
VOID
EFIAPI
UiSwitchSetPosition (
UI_CONTROL *Control,
CONST RECT *Pos
)
{
UI_SWITCH *This;
INT32 Width;
INT32 ThumbWidth;
This = (UI_SWITCH *) Control;
if (!This->InitThumb) {
Width = Pos->right - Pos->left;
ThumbWidth = (Width - SWITCH_BORDER_WIDTH * 2) / 3;
This->ThumbRc.left = SWITCH_BORDER_WIDTH;
This->ThumbRc.top = 3;
This->ThumbRc.right = This->ThumbRc.left + ThumbWidth;
This->ThumbRc.bottom = Pos->bottom - Pos->top - 4;
This->ThumbRange = (Width - SWITCH_BORDER_WIDTH * 2) - ThumbWidth;
if (This->CheckBoxValue) {
This->ThumbPos = This->ThumbRange;
} else {
This->ThumbPos = 0;
}
This->InitThumb = TRUE;
}
UpdateSwitch (Control, Pos);
PARENT_CONTROL_CLASS(CURRENT_CLASS)->SetPosition (Control,Pos);
SetWindowPos (Control->Wnd, HWND_TOP, Pos->left, Pos->top, Pos->right - Pos->left, Pos->bottom - Pos->top, 0);
}
VOID
GetCurrentCheckBoxBkgHsv (
OUT HSV_VALUE *Hsv
)
{
EFI_IMAGE_INPUT *Image;
UINTN Index;
UINTN BufferLen;
Image = GetImageByString (L"@CheckBoxBkg");
ASSERT (Image != NULL);
if (Image == NULL) {
return;
}
BufferLen = Image->Width * Image->Height;
for (Index = 0; Index < BufferLen; Index++) {
if (Image->Bitmap[Index].Reserved != 0) {
RGB2HSV (&Image->Bitmap[Index], Hsv);
return;
}
}
ASSERT (FALSE);
}
STATIC
VOID
UpdateCheckBoxColor (
IN UI_SWITCH *This,
IN CHAR16 *Value
)
{
UI_CONTROL *Control;
HSV_VALUE MenuHsv;
HSV_VALUE HaloHsv;
UINT32 Color;
INT16 HueDiff;
INT8 SaturationDiff;
INT8 ValueDiff;
CHAR16 Str[20];
ASSERT (This != NULL);
if (StrCmp (Value, L"@menucolor") == 0) {
//
// Set as menu color
//
GetCurrentCheckBoxBkgHsv (&HaloHsv);
GetCurrentMenuHsv (&MenuHsv);
if (PcdGet32(PcdH2OLmdeMultiLayout) == 1) {
Color = (UINT32)GetColorValue (L"@menulightcolor");
Color |= 0xFF000000;
RGB2HSV((EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)&Color, &MenuHsv);
}
if (MenuHsv.Hue == 0 && MenuHsv.Saturation == 0 && MenuHsv.Value == 0) {
return;
}
HueDiff = (INT16)(MenuHsv.Hue - HaloHsv.Hue);
SaturationDiff = (INT8) (MenuHsv.Saturation - HaloHsv.Saturation);
ValueDiff = (INT8) (MenuHsv.Value - HaloHsv.Value);
UnicodeSPrint (Str, sizeof (Str), L"%d,%d,%d", HueDiff, SaturationDiff, ValueDiff);
Control = UiFindChildByName (This, L"CheckboxBkg");
UiSetAttribute (Control, L"hsvadjust", Str);
UiSetAttribute (Control, L"background-image-style", L"");
Control = UiFindChildByName (This, L"CheckboxBkg");
UiSetAttribute (Control, L"hsvadjust", Str);
UiSetAttribute (Control, L"background-image-style", L"");
} else if (StrCmp (Value, L"gray") == 0) {
if (PcdGet32(PcdH2OLmdeMultiLayout) == 1) {
UnicodeSPrint (Str, sizeof (Str), L"%d,%d,%d", 0, 238, 10);
Control = UiFindChildByName (This, L"CheckboxBkg");
UiSetAttribute (Control, L"hsvadjust", Str);
return;
}
//
// Grayout
//
UnicodeSPrint (Str, sizeof (Str), L"%d,%d,%d", 0, 0, 0);
Control = UiFindChildByName (This, L"CheckboxBkg");
UiSetAttribute (Control, L"hsvadjust", Str);
UiSetAttribute (Control, L"background-image-style", L"gray");
Control = UiFindChildByName (This, L"CheckboxBorder");
UiSetAttribute (Control, L"background-image-style", L"gray");
}
}
BOOLEAN
EFIAPI
UiSwitchSetAttribute (
UI_CONTROL *Control,
CHAR16 *Name,
CHAR16 *Value
)
{
UI_SWITCH *This;
UI_CONTROL *TextControl;
This = (UI_SWITCH *) Control;
if (StrCmp (Name, L"checkboxvalue") == 0) {
if (StrCmp (Value, L"true") == 0) {
This->CheckBoxValue = TRUE;
} else {
This->CheckBoxValue = FALSE;
}
CONTROL_CLASS (Control)->Invalidate (Control);
} else if (StrCmp (Name, L"switchcolor") == 0) {
UpdateCheckBoxColor (This, Value);
} else if (StrCmp (Name, L"switch-textcolor") == 0) {
TextControl = UiFindChildByName (This, L"CheckboxText");
UiSetAttribute (TextControl, L"textcolor", Value);
} else if (StrCmp (Name, L"disabled") == 0) {
if (StrCmp (Value, L"false") == 0) {
This->Disabled = FALSE;
} else if (StrCmp (Value, L"true") == 0 || StrCmp (Value, L"disabled") == 0) {
This->Disabled = TRUE;
}
} else {
return PARENT_CLASS_SET_ATTRIBUTE (CURRENT_CLASS, Control, Name, Value);
}
CONTROL_CLASS_INVALIDATE (This);
return TRUE;
}
LRESULT
EFIAPI
UiSwitchProc (
HWND Hwnd,
UINT32 Msg,
WPARAM WParam,
LPARAM LParam
)
{
UI_SWITCH *This;
UI_CONTROL *Control;
UI_MANAGER *Manager;
POINT Point;
RECT Rc;
INT32 Pos;
INT32 Dx;
RECT ThumbRc;
This = (UI_SWITCH *) GetWindowLongPtr (Hwnd, 0);
if (This == NULL && Msg != WM_CREATE && Msg != WM_NCCALCSIZE) {
ASSERT (FALSE);
return 0;
}
Control = (UI_CONTROL *)This;
Manager = NULL;
if (Control != NULL) {
Manager = Control->Manager;
}
switch (Msg) {
case WM_CREATE:
This = (UI_SWITCH *) AllocateZeroPool (sizeof (UI_SWITCH));
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);
XmlCreateControl (mSwitchChilds, Control);
break;
case UI_NOTIFY_ACTIVATE:
if (This->Disabled) {
return TRUE;
}
This->CheckBoxValue = !This->CheckBoxValue;
This->ThumbPos = This->CheckBoxValue ? This->ThumbRange : 0;
Manager->GetControlRect (Manager, (UI_CONTROL *)This, &Rc);
UpdateSwitch (Control, &Rc);
SendMessage (Manager->MainWnd, UI_NOTIFY_CLICK, (WPARAM)This, 0);
return TRUE;
case WM_LBUTTONDOWN:
if (This->Disabled) {
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
}
POINTSTOPOINT(Point, LParam);
ThumbRc = This->ThumbRc;
OffsetRect (&ThumbRc, This->ThumbPos, 0);
This->MoveThumb = FALSE;
This->IsHitThumb = FALSE;
if (PtInRect (&ThumbRc, Point)) {
This->IsHitThumb = TRUE;
CONTROL_CLASS(Control)->Invalidate (Control);
}
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
case WM_NCMOUSEMOVE:
if (This->Disabled) {
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
}
POINTSTOPOINT(Point, LParam);
Dx = Point.x - Control->LastX;
GetClientRect (Hwnd, &Rc);
if ((This->IsHitThumb && abs(Dx) > 3) || This->MoveThumb) {
This->MoveThumb = TRUE;
Pos = MAX (0, MIN (This->ThumbPos + Dx, This->ThumbRange));
if (Pos != This->ThumbPos) {
This->ThumbPos = Pos;
Manager->GetControlRect (Manager, (UI_CONTROL *)This, &Rc);
UpdateSwitch (Control, &Rc);
Control->LastX = Point.x;
}
} else {
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
}
break;
case WM_MOUSELEAVE:
This->IsHitThumb = FALSE;
This->MoveThumb = FALSE;
break;
case WM_LBUTTONUP:
if (This->Disabled) {
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
}
if (!This->MoveThumb) {
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
}
break;
case WM_NCLBUTTONUP:
if (This->Disabled) {
This->IsHitThumb = FALSE;
if (This->MoveThumb) {
This->MoveThumb = FALSE;
if (GetCapture () == Hwnd) {
CONTROL_CLASS_SET_STATE (Control, 0, UISTATE_PRESSED | UISTATE_CAPTURED | UISTATE_PREPRESSED);
Control->Class->Invalidate (Control);
ReleaseCapture ();
}
}
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
}
This->IsHitThumb = FALSE;
if (This->MoveThumb) {
This->MoveThumb = FALSE;
if (GetCapture () == Hwnd) {
CONTROL_CLASS_SET_STATE (Control, 0, UISTATE_PRESSED | UISTATE_CAPTURED | UISTATE_PREPRESSED);
Control->Class->Invalidate (Control);
ReleaseCapture ();
}
GetClientRect (Hwnd, &Rc);
if (This->CheckBoxValue) {
if (This->ThumbPos < This->ThumbRange / 2) {
SendMessage (Hwnd, UI_NOTIFY_ACTIVATE, 0, 0);
} else {
This->ThumbPos = This->ThumbRange;
UpdateSwitch (Control, &Rc);
}
} else {
if (This->ThumbPos >= This->ThumbRange / 2) {
SendMessage (Hwnd, UI_NOTIFY_ACTIVATE, 0, 0);
} else {
This->ThumbPos = 0;
UpdateSwitch (Control, &Rc);
}
}
} else {
if (!Control->Dragged && CONTROL_CLASS_GET_STATE (Control) & (UISTATE_PRESSED | UISTATE_CAPTURED)) {
SendMessage (Hwnd, UI_NOTIFY_ACTIVATE, 0, 0);
break;
}
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
}
break;
case UI_NOTIFY_PAINT:
if (WParam == PAINT_TEXT || WParam == PAINT_BKCOLOR || WParam == PAINT_STATUSIMAGE) {
break;
}
PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
break;
case WM_NCHITTEST:
return HTCLIENT;
default:
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
}
return 0;
}
UI_SWITCH_CLASS *
EFIAPI
GetSwitchClass (
VOID
)
{
if (CURRENT_CLASS != NULL) {
return CURRENT_CLASS;
}
InitUiClass ((UI_CONTROL_CLASS **)&CURRENT_CLASS, sizeof (*CURRENT_CLASS), L"Switch", (UI_CONTROL_CLASS *)GetControlClass());
if (CURRENT_CLASS == NULL) {
return NULL;
}
((UI_CONTROL_CLASS *)CURRENT_CLASS)->WndProc = UiSwitchProc;
((UI_CONTROL_CLASS *)CURRENT_CLASS)->SetAttribute = UiSwitchSetAttribute;
((UI_CONTROL_CLASS *)CURRENT_CLASS)->SetPosition = UiSwitchSetPosition;
return CURRENT_CLASS;
}