476 lines
14 KiB
C
476 lines
14 KiB
C
/** @file
|
|
Form Panel
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 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 <Library/LayoutLib.h>
|
|
#include <Library/HiiDbLib.h>
|
|
#include <Library/HiiStringLib.h>
|
|
#include <Library/HiiConfigAccessLib.h>
|
|
#include <Library/UefiHiiServicesLib.h>
|
|
#include <Guid/H2OFormDialog.h>
|
|
#include "H2ODisplayEngineLocalMetro.h"
|
|
#include "MetroUi.h"
|
|
#include "MetroDialog.h"
|
|
#include "H2OPanels.h"
|
|
#include "StatementControls.h"
|
|
|
|
#define FORM_PANEL_TIMER_ID 1
|
|
STATIC FORM_PANEL_CLASS *mFormPanelClass = NULL;
|
|
#define CURRENT_CLASS mFormPanelClass
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
FormPanelSendChangeQ (
|
|
IN UI_CONTROL *Control
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UI_CONTROL *Child;
|
|
UINTN Index;
|
|
H2O_STATEMENT_CONTROL *StatementControl;
|
|
|
|
if (Control == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
for (Index = 0; Index < Control->ItemCount; Index++) {
|
|
Child = Control->Items[Index];
|
|
if (IsStatementControlClassName (Child->Class->ClassName)) {
|
|
StatementControl = (H2O_STATEMENT_CONTROL *) Child;
|
|
Status = StatementControl->OnSendChangeQ (StatementControl);
|
|
} else {
|
|
Status = FormPanelSendChangeQ (Child);
|
|
}
|
|
if (!EFI_ERROR (Status)) {
|
|
//
|
|
// Send Change Q by first StatementControl which value was changed
|
|
//
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FormPanelChkAction (
|
|
IN UI_CONTROL *Control
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
HWND FocusedWnd;
|
|
UI_CONTROL *FocusedControl;
|
|
UI_CONTROL *ParentControl;
|
|
H2O_ACTION_BUTTON *ActionButton;
|
|
H2O_ACTION_BUTTON_ACTION Action;
|
|
|
|
if (Control == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
FocusedWnd = GetFocus ();
|
|
FocusedControl = GetUiControl (FocusedWnd);
|
|
ParentControl = (FocusedWnd->parent != NULL) ? GetUiControl (FocusedWnd->parent) : NULL;
|
|
|
|
if (FocusedControl != NULL && StrCmp (FocusedControl->Class->ClassName, L"ActionButton") == 0) {
|
|
ActionButton = (H2O_ACTION_BUTTON *)FocusedControl;
|
|
} else if (ParentControl != NULL && StrCmp (ParentControl->Class->ClassName, L"ActionButton") == 0) {
|
|
ActionButton = (H2O_ACTION_BUTTON *)ParentControl;
|
|
} else {
|
|
ActionButton = NULL;
|
|
}
|
|
|
|
if (ActionButton != NULL) {
|
|
Action = ActionButton->OnActive (ActionButton);
|
|
switch (Action) {
|
|
|
|
case ActionButtonDialogOk:
|
|
Status = FormPanelSendChangeQ (Control);
|
|
if (EFI_ERROR (Status)) {
|
|
SendShutDNotify ();
|
|
}
|
|
return EFI_SUCCESS;
|
|
|
|
case ActionButtonDialogCancel:
|
|
SendShutDNotify ();
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
STATIC
|
|
VOID
|
|
FormPanelCallAllStatementControlProc (
|
|
IN UI_CONTROL *Control,
|
|
IN UINT Msg,
|
|
IN WPARAM WParam,
|
|
IN LPARAM LParam
|
|
)
|
|
{
|
|
UI_CONTROL *Child;
|
|
UINTN Index;
|
|
|
|
if (Control == NULL) {
|
|
return;
|
|
}
|
|
|
|
for (Index = 0; Index < Control->ItemCount; Index++) {
|
|
Child = Control->Items[Index];
|
|
if (IsStatementControlClassName (Child->Class->ClassName)) {
|
|
Child->Class->WndProc (Child->Wnd, Msg, WParam, LParam);
|
|
} else {
|
|
FormPanelCallAllStatementControlProc (Child, Msg, WParam, LParam);
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FormPanelCallAllChildProc (
|
|
IN UI_CONTROL_CLASS *CurrentClass,
|
|
IN UI_CONTROL *Control,
|
|
IN UINT Msg,
|
|
IN WPARAM WParam,
|
|
IN LPARAM LParam
|
|
)
|
|
{
|
|
UI_CONTROL *Parent;
|
|
|
|
if (CurrentClass == NULL || Control == NULL) {
|
|
return;
|
|
}
|
|
|
|
Parent = NULL;
|
|
if (Control->Class == CurrentClass) {
|
|
Parent = Control;
|
|
} else {
|
|
Parent = Control->Class->GetParent (Control);
|
|
while (TRUE) {
|
|
if (Parent == NULL) {
|
|
return;
|
|
}
|
|
if (Parent->Class == CurrentClass) {
|
|
break;
|
|
}
|
|
Parent = Parent->Class->GetParent (Parent);
|
|
}
|
|
}
|
|
if (Parent == NULL) {
|
|
return;
|
|
}
|
|
|
|
FormPanelCallAllStatementControlProc (Parent, Msg, WParam, LParam);
|
|
}
|
|
|
|
EFI_STATUS
|
|
FormPanelCreateChildByVfrForm (
|
|
IN UI_CONTROL *Control,
|
|
IN H2O_PANEL_INFO *Panel,
|
|
IN EFI_GUID *FormsetId,
|
|
IN UINT16 FormId,
|
|
IN RECT *FormPanelRect,
|
|
OUT UINT8 *RefreshInterval
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
H2O_FORM_BROWSER_P *Page;
|
|
UINT32 Index;
|
|
UI_CONTROL *Child;
|
|
UINT32 TabOrder;
|
|
H2O_FORM_BROWSER_S *Statement;
|
|
H2O_PROPERTY_VALUE ControlTypePropValue;
|
|
H2O_PROPERTY_VALUE SizePropValue;
|
|
H2O_PROPERTY_VALUE ColorPropValue;
|
|
H2O_PROPERTY_VALUE KerwordPropValue;
|
|
RECT StatementRect;
|
|
CHAR16 *ClassName;
|
|
CHAR16 *ImageStyle;
|
|
UINT8 RefreshTime;
|
|
BOOLEAN IsStatementControl;
|
|
CHAR16 Str[100];
|
|
|
|
if (Panel == NULL || FormsetId == NULL || FormPanelRect == NULL || RefreshInterval == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = gFB->GetPInfoByForm (gFB, FormsetId, FormId, &Page);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
if (Page->NumberOfStatementIds == 0 || Page->StatementIds == NULL) {
|
|
FreePool (Page);
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
RefreshTime = 0;
|
|
TabOrder = 0;
|
|
for (Index = 0; Index < Page->NumberOfStatementIds; Index++) {
|
|
Statement = NULL;
|
|
Status = gFB->GetSInfo (gFB, Page->PageId, Page->StatementIds[Index], &Statement);
|
|
if (EFI_ERROR (Status) || Statement == NULL) {
|
|
continue;
|
|
}
|
|
|
|
if (Statement->QuestionId != 0 && Statement->RefreshInterval != 0) {
|
|
RefreshTime = (RefreshTime == 0) ? Statement->RefreshInterval : MIN (Statement->RefreshInterval, RefreshTime);
|
|
}
|
|
|
|
//
|
|
// Create a control which's class is from control type
|
|
//
|
|
ClassName = NULL;
|
|
Status = GetStatementPropValue ("control-type", Statement, Panel, 0, 0, NULL, &ControlTypePropValue);
|
|
if (!EFI_ERROR (Status)) {
|
|
ClassName = GetClassNameByControlType (&ControlTypePropValue.H2OValue.Value.Guid);
|
|
}
|
|
if (ClassName == NULL) {
|
|
ClassName = L"Label";
|
|
}
|
|
|
|
Child = CreateAddControl (ClassName, Control);
|
|
ASSERT(Child != NULL);
|
|
if (Child == NULL) {
|
|
continue;
|
|
}
|
|
UnicodeSPrint (Str, sizeof(Str), L"name='FormPanel%08x_%08x'", Page->PageId,Statement->StatementId);
|
|
UiApplyAttributeList (Child, Str);
|
|
|
|
//
|
|
// For Statement Control
|
|
//
|
|
IsStatementControl = IsStatementControlClassName (ClassName);
|
|
if (IsStatementControl) {
|
|
TabOrder++;
|
|
UnicodeSPrint (Str, sizeof(Str), L"statement='0x%p' taborder='%d'", Statement, TabOrder);
|
|
UiApplyAttributeList (Child, Str);
|
|
}
|
|
|
|
Status = GetStatementRect (Statement, Panel, FormPanelRect, &StatementRect);
|
|
if (!EFI_ERROR (Status)) {
|
|
UnicodeSPrint (
|
|
Str,
|
|
sizeof(Str),
|
|
L"float='true' left='%d' top='%d' width='%d' height='%d'",
|
|
StatementRect.left,
|
|
StatementRect.top,
|
|
(StatementRect.right - StatementRect.left),
|
|
(StatementRect.bottom - StatementRect.top)
|
|
);
|
|
UiApplyAttributeList (Child, Str);
|
|
}
|
|
|
|
Status = GetStatementPropValue ("background-color", Statement, Panel, 0, 0, NULL, &ColorPropValue);
|
|
if (!EFI_ERROR (Status)) {
|
|
UnicodeSPrint (Str, sizeof(Str), L"background-color='0x%08x'", ColorPropValue.H2OValue.Value.U32);
|
|
UiApplyAttributeList (Child, Str);
|
|
}
|
|
|
|
if (StrStr (ClassName, L"ActionButton") != NULL ||
|
|
StrStr (ClassName, L"Label") != NULL) {
|
|
Status = GetStatementPropValue ("font-size", Statement, Panel, 0, 0, NULL, &SizePropValue);
|
|
if (EFI_ERROR (Status)) {
|
|
SizePropValue.H2OValue.Value.U32 = 0;
|
|
}
|
|
Status = GetStatementPropValue ("color", Statement, Panel, 0, 0, NULL, &ColorPropValue);
|
|
if (EFI_ERROR (Status)) {
|
|
ColorPropValue.H2OValue.Value.U32 = 0;
|
|
}
|
|
UnicodeSPrint (
|
|
Str,
|
|
sizeof(Str),
|
|
L"font-size='%d' textcolor='0x%08x' ",
|
|
(SizePropValue.H2OValue.Value.U32 == 0)? 20 : SizePropValue.H2OValue.Value.U32,
|
|
ColorPropValue.H2OValue.Value.U32
|
|
);
|
|
UiApplyAttributeList (Child, Str);
|
|
UiSetAttribute (Child, L"text", Statement->Prompt);
|
|
}
|
|
|
|
if (Statement->Image != NULL) {
|
|
ImageStyle = L"stretch";
|
|
Status = GetStatementPropValue ("filter", Statement, Panel, 0, 0, NULL, &KerwordPropValue);
|
|
if (!EFI_ERROR (Status) && KerwordPropValue.H2OValue.Type == H2O_VALUE_TYPE_UINT16) {
|
|
if ((KerwordPropValue.H2OValue.Value.U16 | KEYWORD_FILTER_BRIGHTNESS) == KEYWORD_FILTER_BRIGHTNESS) {
|
|
ImageStyle = L"stretch|light";
|
|
} else if ((KerwordPropValue.H2OValue.Value.U16 | KEYWORD_FILTER_GRAYSCALE) == KEYWORD_FILTER_GRAYSCALE) {
|
|
ImageStyle = L"stretch|gray";
|
|
}
|
|
}
|
|
UnicodeSPrint (Str, sizeof(Str), L"background-image='0x%p' background-image-style='%s'", Statement->Image, ImageStyle);
|
|
UiApplyAttributeList (Child, Str);
|
|
}
|
|
|
|
FreePool (Statement);
|
|
}
|
|
FreePool (Page);
|
|
|
|
*RefreshInterval = RefreshTime;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FormPanelCreateChildControls (
|
|
IN UI_CONTROL *Control
|
|
)
|
|
{
|
|
H2O_PANEL_INFO *PanelInfo;
|
|
EFI_STATUS Status;
|
|
RECT Rect;
|
|
UINT8 RefreshInterval;
|
|
RECT ScreenField;
|
|
|
|
if (Control == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PanelInfo = (H2O_PANEL_INFO *) GetWindowLongPtr (Control->Wnd, GWLP_USERDATA);
|
|
if (PanelInfo == NULL || PanelInfo->TargetFormId == 0) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
if (Control == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ScreenField.left = 0;
|
|
ScreenField.top = 0;
|
|
ScreenField.right = (INT32) GetSystemMetrics (SM_CXSCREEN);
|
|
ScreenField.bottom = (INT32) GetSystemMetrics (SM_CYSCREEN);
|
|
|
|
Status = GetFormPanelRect (
|
|
&PanelInfo->TargetFormsetGuid,
|
|
PanelInfo->TargetFormId,
|
|
PanelInfo,
|
|
&ScreenField,
|
|
&Rect
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
CONTROL_CLASS(Control)->RemoveAllChild (Control);
|
|
|
|
Status = FormPanelCreateChildByVfrForm (
|
|
Control,
|
|
PanelInfo,
|
|
&PanelInfo->TargetFormsetGuid,
|
|
PanelInfo->TargetFormId,
|
|
&Rect,
|
|
&RefreshInterval
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
KillTimer (Control->Wnd, (UINT) FORM_PANEL_TIMER_ID);
|
|
if (RefreshInterval != 0) {
|
|
SetTimer (Control->Wnd, FORM_PANEL_TIMER_ID, (UINT) RefreshInterval == 1 ? 300 : RefreshInterval * 1000, NULL);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
LRESULT
|
|
EFIAPI
|
|
FormPanelProc (
|
|
IN HWND Hwnd,
|
|
IN UINT32 Msg,
|
|
IN WPARAM WParam,
|
|
IN LPARAM LParam
|
|
)
|
|
{
|
|
FORM_PANEL *This;
|
|
UI_CONTROL *Control;
|
|
EFI_STATUS Status;
|
|
|
|
This = (FORM_PANEL *) GetUiControl (Hwnd);
|
|
if (This == NULL && Msg != WM_CREATE && Msg != WM_NCCALCSIZE) {
|
|
ASSERT (FALSE);
|
|
return 0;
|
|
}
|
|
Control = (UI_CONTROL *)This;
|
|
|
|
switch (Msg) {
|
|
|
|
case WM_CREATE:
|
|
This = (FORM_PANEL *) AllocateZeroPool (sizeof (FORM_PANEL));
|
|
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);
|
|
break;
|
|
|
|
case FB_NOTIFY_REPAINT:
|
|
if (!This->FormPanelChildsInitialized) {
|
|
This->FormPanelChildsInitialized = TRUE;
|
|
FormPanelCreateChildControls (Control);
|
|
}
|
|
PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
|
|
CONTROL_CLASS_INVALIDATE (Control);
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
if (WParam == FORM_PANEL_TIMER_ID) {
|
|
FormPanelCreateChildControls (Control);
|
|
}
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
KillTimer (Hwnd, FORM_PANEL_TIMER_ID);
|
|
break;
|
|
|
|
case UI_NOTIFY_CLICK:
|
|
case UI_NOTIFY_CARRIAGE_RETURN:
|
|
Status = FormPanelChkAction (Control);
|
|
if (!EFI_ERROR (Status)) {
|
|
break;
|
|
}
|
|
FormPanelCallAllChildProc ((UI_CONTROL_CLASS *)CURRENT_CLASS, Control, Msg, WParam, LParam);
|
|
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
|
|
|
|
case WM_NCHITTEST:
|
|
return HTCLIENT;
|
|
|
|
default:
|
|
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
FORM_PANEL_CLASS *
|
|
EFIAPI
|
|
GetFormPanelClass (
|
|
VOID
|
|
)
|
|
{
|
|
if (CURRENT_CLASS != NULL) {
|
|
return CURRENT_CLASS;
|
|
}
|
|
|
|
InitUiClass ((UI_CONTROL_CLASS **)&CURRENT_CLASS, sizeof (*CURRENT_CLASS), L"FormPanel", (UI_CONTROL_CLASS *)GetControlClass());
|
|
if (CURRENT_CLASS == NULL) {
|
|
return NULL;
|
|
}
|
|
((UI_CONTROL_CLASS *)CURRENT_CLASS)->WndProc = FormPanelProc;
|
|
|
|
return CURRENT_CLASS;
|
|
}
|
|
|