541 lines
13 KiB
C
541 lines
13 KiB
C
/** @file
|
|
UI Common Controls
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 2021, 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"
|
|
|
|
STATIC UI_EDIT_CLASS *mEditClass = NULL;
|
|
#define CURRENT_CLASS mEditClass
|
|
|
|
VOID
|
|
UiEditCreate (
|
|
UI_EDIT *This
|
|
)
|
|
{
|
|
UI_CONTROL *Control;
|
|
SIZE Size;
|
|
|
|
Control = (UI_CONTROL *) This;
|
|
|
|
GetTextExtentPoint32 (Control->Manager->PaintDC, L"X", 1, &Size);
|
|
This->CharHeight = Size.cy;
|
|
This->EditPos = 0;
|
|
This->MinValue = 0;
|
|
This->MaxValue = 0;
|
|
This->Step = 0;
|
|
This->ValueType = NOT_VALUE;
|
|
This->ValueSize = 8;
|
|
}
|
|
|
|
VOID
|
|
UiEditSetPasswordMode (
|
|
UI_EDIT *This,
|
|
BOOLEAN PasswordMode
|
|
)
|
|
{
|
|
if (This->IsPasswordMode != PasswordMode) {
|
|
This->IsPasswordMode = PasswordMode;
|
|
CONTROL_CLASS(This)->Invalidate ((UI_CONTROL *)This);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
UiEditSetReadOnly (
|
|
UI_EDIT *This,
|
|
BOOLEAN ReadOnly
|
|
)
|
|
{
|
|
if (This->IsReadOnly != ReadOnly) {
|
|
This->IsReadOnly = ReadOnly;
|
|
CONTROL_CLASS(This)->Invalidate ((UI_CONTROL *)This);
|
|
}
|
|
}
|
|
|
|
|
|
SIZE
|
|
EFIAPI
|
|
UiEditEstimateSize (
|
|
UI_CONTROL *Control,
|
|
SIZE AvailableSize
|
|
)
|
|
{
|
|
|
|
RECT TextRc;
|
|
UI_EDIT *This;
|
|
SIZE Size;
|
|
UI_LABEL *Label;
|
|
UINT32 Style;
|
|
|
|
|
|
This = (UI_EDIT *) Control;
|
|
Label = (UI_LABEL *) Control;
|
|
|
|
if (IS_CONTROL_HEIGHT_DEFINED(Control)) {
|
|
AvailableSize.cx = MIN (AvailableSize.cx, CalculateControlDisplayWidth (Control, AvailableSize));
|
|
}
|
|
|
|
if (Label->Text == '\0') {
|
|
Size.cx = CalculateControlDisplayWidth (Control, AvailableSize);
|
|
Size.cy = GetControlFontSize (Control);
|
|
return Size;
|
|
}
|
|
|
|
SetRect (&TextRc, 0, 0, AvailableSize.cx, 9999);
|
|
//TextRc.left += This->TextPadding.left;
|
|
//TextRc.right -= This->TextPadding.right;
|
|
|
|
Style = DT_WORDBREAK | DT_CALCRECT;
|
|
if (Label->ShowHtmlText) {
|
|
Style |= DT_HTML_TEXT;
|
|
}
|
|
|
|
UiPaintText (
|
|
Control->Manager->PaintDC,
|
|
GetControlFontSize (Control),
|
|
&TextRc,
|
|
Label->Text,
|
|
INVALID_COLOR,
|
|
INVALID_COLOR,
|
|
Style
|
|
);
|
|
|
|
Size.cx = TextRc.right - TextRc.left; // + This->TextPadding.left + This->TextPadding.right;
|
|
Size.cy = TextRc.bottom - TextRc.top; // + This->TextPadding.top + This->TextPadding.bottom;
|
|
|
|
if (IS_CONTROL_HEIGHT_DEFINED (Control)) {
|
|
Size.cy = CalculateControlDisplayHeight (Control, AvailableSize);
|
|
}
|
|
|
|
if (IS_CONTROL_WIDTH_DEFINED (Control)) {
|
|
Size.cx = CalculateControlDisplayWidth (Control, AvailableSize);
|
|
}
|
|
|
|
return Size;
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
EFIAPI
|
|
UiEditSetAttribute (
|
|
UI_CONTROL *Control,
|
|
CHAR16 *Name,
|
|
CHAR16 *Value
|
|
)
|
|
{
|
|
UI_EDIT *This;
|
|
EFI_STATUS Status;
|
|
|
|
This = (UI_EDIT *) Control;
|
|
|
|
if (StrCmp (Name, L"valuetype") == 0) {
|
|
if (StrCmp (Value, L"dec") == 0) {
|
|
This->ValueType = DEC_VALUE;
|
|
} else if (StrCmp (Value, L"hex") == 0) {
|
|
This->ValueType = HEX_VALUE;
|
|
} else if (StrCmp (Value, L"signeddec") == 0) {
|
|
This->ValueType = SIGNED_DEC_VALUE;
|
|
} else {
|
|
This->ValueType = NOT_VALUE;
|
|
}
|
|
} else if (StrCmp (Name, L"password") == 0) {
|
|
UiEditSetPasswordMode (This, (StrCmp (Value, L"true") == 0));
|
|
} else if (StrCmp (Name, L"readonly") == 0) {
|
|
UiEditSetReadOnly (This, (StrCmp (Value, L"true") == 0));
|
|
} else if (StrCmp (Name, L"maxlength") == 0) {
|
|
This->MaxLength = (UINT32) StrToUInt (Value, 10, &Status);
|
|
} else if (StrCmp (Name, L"maxvalue") == 0) {
|
|
This->MaxValue = StrToUInt (Value, 10, &Status);
|
|
} else if (StrCmp (Name, L"minvalue") == 0) {
|
|
This->MinValue = StrToUInt (Value, 10, &Status);
|
|
} else if (StrCmp (Name, L"valuesize") == 0) {
|
|
This->ValueSize = (UINT8)StrToUInt (Value, 10, &Status);
|
|
} else {
|
|
return PARENT_CLASS_SET_ATTRIBUTE (CURRENT_CLASS, Control, Name, Value);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
UiEditKeyDown (
|
|
HWND Hwnd,
|
|
WPARAM WParam,
|
|
LPARAM LParam
|
|
)
|
|
{
|
|
|
|
UI_CONTROL *Control;
|
|
UI_EDIT *Edit;
|
|
BOOLEAN ReDraw;
|
|
UINTN LastEditPos;
|
|
SIZE Size;
|
|
UI_MANAGER *Manager;
|
|
UI_LABEL *Label;
|
|
|
|
Control = GetUiControl (Hwnd);
|
|
Edit = (UI_EDIT *) Control;
|
|
Label = (UI_LABEL *) Control;
|
|
LastEditPos = Edit->EditPos;
|
|
Manager = Control->Manager;
|
|
|
|
|
|
ReDraw = FALSE;
|
|
|
|
switch (WParam) {
|
|
|
|
case VK_LEFT:
|
|
if (Edit->EditPos > 0) {
|
|
Edit->EditPos--;
|
|
}
|
|
|
|
break;
|
|
|
|
case VK_RIGHT:
|
|
if (Edit->EditPos < StrLen (Label->Text)) {
|
|
Edit->EditPos++;
|
|
}
|
|
break;
|
|
|
|
case VK_HOME:
|
|
Edit->EditPos = 0;
|
|
break;
|
|
|
|
case VK_END:
|
|
Edit->EditPos = (UINT32) StrLen (Label->Text);
|
|
break;
|
|
|
|
|
|
case VK_BACK:
|
|
if (Edit->EditPos > 0) {
|
|
Edit->EditPos--;
|
|
memmove (Label->Text + Edit->EditPos,
|
|
Label->Text + Edit->EditPos + 1,
|
|
(StrLen (Label->Text) - Edit->EditPos + 1) * sizeof (CHAR16));
|
|
ReDraw = TRUE;
|
|
}
|
|
break;
|
|
|
|
case VK_DELETE:
|
|
if (Edit->EditPos < StrLen (Label->Text)) {
|
|
memmove (Label->Text + Edit->EditPos,
|
|
Label->Text + Edit->EditPos + 1,
|
|
(StrLen (Label->Text) - Edit->EditPos + 1) * sizeof (CHAR16));
|
|
ReDraw = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (LastEditPos != Edit->EditPos || ReDraw) {
|
|
if (Edit->EditPos != 0) {
|
|
GetTextExtentPoint32 (Manager->PaintDC, Label->Text, (UINT32)Edit->EditPos, &Size);
|
|
}
|
|
CONTROL_CLASS(Edit)->Invalidate (Control);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
UiEditCharPress (
|
|
HWND Hwnd,
|
|
WPARAM WParam,
|
|
LPARAM LParam
|
|
)
|
|
{
|
|
CHAR16 Char;
|
|
CHAR16 *OldStr;
|
|
CHAR16 *NewStr;
|
|
UI_EDIT *This;
|
|
SIZE Size;
|
|
UI_CONTROL *Control;
|
|
UI_LABEL *Label;
|
|
UINT8 NumericFlags;
|
|
|
|
|
|
This = (UI_EDIT *) GetUiControl (Hwnd);
|
|
Control = (UI_CONTROL *)This;
|
|
Label = (UI_LABEL *) This;
|
|
|
|
ASSERT (Label->Text != NULL);
|
|
if (Label->Text == NULL) {
|
|
return ;
|
|
}
|
|
|
|
if (This->IsReadOnly) {
|
|
return ;
|
|
}
|
|
|
|
Char = LOWORD (WParam);
|
|
|
|
switch (Char) {
|
|
case 0x00: /* NULL */
|
|
case 0x07: /* BEL */
|
|
case 0x08: /* BS */
|
|
case 0x09: /* HT */
|
|
case 0x0A: /* LF */
|
|
case 0x0B: /* VT */
|
|
case 0x0C: /* FF */
|
|
case 0x1B: /* Escape */
|
|
return ;
|
|
case 0x0D: /* enter */
|
|
if (mSetupMouse != NULL) {
|
|
mSetupMouse->CloseKeyboard (mSetupMouse);
|
|
}
|
|
return ;
|
|
}
|
|
|
|
if (This->MaxLength != 0 && StrLen (Label->Text) >= This->MaxLength) {
|
|
if (FeaturePcdGet (PcdH2OBdsCpFormBrowserInputPasswordTooLongSupported)) {
|
|
if (This->IsPasswordMode) {
|
|
H2O_BDS_CP_FORM_BROWSER_INPUT_PASSWORD_TOO_LONG_DATA FormBrowserInputPaswwordTooLong;
|
|
|
|
FormBrowserInputPaswwordTooLong.Size = sizeof (H2O_BDS_CP_FORM_BROWSER_INPUT_PASSWORD_TOO_LONG_DATA);
|
|
FormBrowserInputPaswwordTooLong.Status = H2O_CP_TASK_NORMAL;
|
|
|
|
DEBUG_CP ((DEBUG_INFO, "Checkpoint Trigger: %g\n", &gH2OBdsCpFormBrowserInputPasswordTooLongGuid));
|
|
H2OCpTrigger (&gH2OBdsCpFormBrowserInputPasswordTooLongGuid, &FormBrowserInputPaswwordTooLong);
|
|
DEBUG_CP ((DEBUG_INFO, "Checkpoint Result: %x\n", FormBrowserInputPaswwordTooLong.Status));
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
//
|
|
// insert data
|
|
//
|
|
OldStr = Label->Text;
|
|
NewStr = AllocatePool (StrSize (OldStr) + sizeof (CHAR16));
|
|
if (NewStr == NULL) {
|
|
return;
|
|
}
|
|
if (This->EditPos != 0) {
|
|
CopyMem (NewStr, OldStr, This->EditPos * sizeof (CHAR16));
|
|
}
|
|
|
|
NewStr[This->EditPos] = Char;
|
|
|
|
CopyMem (NewStr + This->EditPos + 1,
|
|
OldStr + This->EditPos,
|
|
(StrLen (OldStr) - This->EditPos + 1) * sizeof (CHAR16));
|
|
|
|
|
|
if (This->ValueType == DEC_VALUE || This->ValueType == HEX_VALUE || This->ValueType == SIGNED_DEC_VALUE) {
|
|
NumericFlags = ConvertToIfrNumericFlags (This->ValueType == HEX_VALUE, This->ValueType == SIGNED_DEC_VALUE, This->ValueSize);
|
|
if (!IfrNumericIsEditStrValid (NumericFlags, NewStr, This->MinValue, This->MaxValue)) {
|
|
FreePool (NewStr);
|
|
return ;
|
|
}
|
|
}
|
|
|
|
FreePool (OldStr);
|
|
Label->Text = NewStr;
|
|
This->EditPos++;
|
|
|
|
GetTextExtentPoint32 (Control->Manager->PaintDC, Label->Text, This->EditPos, &Size);
|
|
//SetCaretPos (Size.cx, 1);
|
|
CONTROL_CLASS(This)->Invalidate (Control);
|
|
return ;
|
|
}
|
|
|
|
|
|
|
|
LRESULT
|
|
EFIAPI
|
|
UiEditProc (
|
|
HWND Hwnd,
|
|
UINT32 Msg,
|
|
WPARAM WParam,
|
|
LPARAM LParam
|
|
)
|
|
{
|
|
UI_EDIT *This;
|
|
UI_CONTROL *Control;
|
|
UI_MANAGER *Manager;
|
|
//POINT Point;
|
|
RECT Rc;
|
|
SIZE Size;
|
|
LRESULT Ret;
|
|
CHAR16 *StrBuf;
|
|
CHAR16 *TmpPtr;
|
|
UINTN Len;
|
|
UINTN Index;
|
|
KEYBOARD_ATTRIBUTES KeyboardAttributes;
|
|
UI_LABEL *Label;
|
|
|
|
|
|
Control = (UI_CONTROL *) GetWindowLongPtr (Hwnd, 0);
|
|
if (Control == NULL && Msg != WM_CREATE && Msg != WM_NCCALCSIZE) {
|
|
ASSERT (FALSE);
|
|
return 0;
|
|
}
|
|
This = (UI_EDIT *) Control;
|
|
Label = (UI_LABEL *) Control;
|
|
Manager = NULL;
|
|
if (Control != NULL) {
|
|
Manager = Control->Manager;
|
|
}
|
|
|
|
switch (Msg) {
|
|
|
|
case WM_CREATE:
|
|
This = (UI_EDIT *) AllocateZeroPool (sizeof (UI_EDIT));
|
|
if (This != NULL) {
|
|
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);
|
|
UiEditCreate (This);
|
|
Control->Class = (UI_CONTROL_CLASS *) GetClassLongPtr (Hwnd, 0);
|
|
Control->BkColor = 0xFFD0D0D0;
|
|
Control->BorderColor = 0xFF808080;
|
|
SetWindowLongPtr (
|
|
Control->Wnd,
|
|
GWL_EXSTYLE, GetWindowLongPtr (Control->Wnd, GWL_EXSTYLE) & ~WS_EX_NOACTIVATE
|
|
);
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
if ((CONTROL_CLASS_GET_STATE (Control) & UISTATE_CAPTURED) != 0) {
|
|
return 0;
|
|
}
|
|
CONTROL_CLASS_SET_STATE (Control, UISTATE_CAPTURED, 0);
|
|
|
|
if (This->IsReadOnly) {
|
|
return 0;
|
|
}
|
|
|
|
// CreateCaret(Hwnd, NULL, 1, This->CharHeight);
|
|
//This->EditPos = 0;
|
|
This->EditPos = (UINT32) StrLen (Label->Text);
|
|
GetTextExtentPoint32 (Control->Manager->PaintDC, Label->Text, This->EditPos, &Size);
|
|
// SetCaretPos (Size.cx, 1);
|
|
// ShowCaret (Hwnd);
|
|
SendMessage (Manager->MainWnd, UI_NOTIFY_EDITFOCUS, (WPARAM)Control, 0);
|
|
Control->BorderColor = 0xFF800000;
|
|
// mSetupMouse->DrawKeyboard (mSetupMouse, 0, 0);
|
|
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
|
|
|
|
case WM_KILLFOCUS:
|
|
CONTROL_CLASS_SET_STATE (Control, 0, UISTATE_CAPTURED);
|
|
// HideCaret(Hwnd);
|
|
// DestroyCaret();
|
|
SendMessage (Manager->MainWnd, UI_NOTIFY_BLUR, (WPARAM)Control, 0);
|
|
Control->BorderColor = 0xFF808080;
|
|
if (mSetupMouse != NULL) {
|
|
mSetupMouse->CloseKeyboard (mSetupMouse);
|
|
}
|
|
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
|
|
|
|
|
|
case WM_CHAR:
|
|
UiEditCharPress (Hwnd, WParam, LParam);
|
|
break;
|
|
|
|
case WM_KEYDOWN:
|
|
if (WParam == VK_RETURN) {
|
|
SendMessage (Manager->MainWnd, UI_NOTIFY_CARRIAGE_RETURN, (WPARAM) Control, 0);
|
|
} else {
|
|
UiEditKeyDown (Hwnd, WParam, LParam);
|
|
}
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
// if (GetCapture () != Hwnd) {
|
|
// SetCapture (Hwnd);
|
|
// SetFocus (Hwnd);
|
|
// return 0;
|
|
// }
|
|
//
|
|
PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
|
|
GetWindowRect (Hwnd, &Rc);
|
|
if ((GetWindowLongPtr (Hwnd, GWL_STYLE) & WS_DISABLED) == 0) {
|
|
if (mSetupMouse != NULL) {
|
|
mSetupMouse->GetKeyboardAttributes (mSetupMouse, &KeyboardAttributes);
|
|
if (!KeyboardAttributes.IsStart) {
|
|
mSetupMouse->StartKeyboard (mSetupMouse, Rc.left, Rc.bottom + 20);
|
|
}
|
|
}
|
|
}
|
|
// ReleaseCapture ();
|
|
// if (
|
|
//
|
|
// ReleaseCapture ();
|
|
// This->StateFlags &= ~UISTATE_CAPTURED;
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
if (mSetupMouse != NULL) {
|
|
mSetupMouse->GetKeyboardAttributes (mSetupMouse, &KeyboardAttributes);
|
|
if (KeyboardAttributes.IsStart) {
|
|
mSetupMouse->CloseKeyboard (mSetupMouse);
|
|
}
|
|
}
|
|
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
|
|
|
|
case WM_NCHITTEST:
|
|
return HTCLIENT;
|
|
break;
|
|
|
|
case UI_NOTIFY_PAINT:
|
|
if (WParam == PAINT_TEXT && This->IsPasswordMode) {
|
|
Len = StrLen (Label->Text);
|
|
if (Len != 0) {
|
|
TmpPtr = Label->Text;
|
|
StrBuf = AllocateZeroPool ((Len + 1) * sizeof (CHAR16));
|
|
if (StrBuf == NULL) {
|
|
return 0;
|
|
}
|
|
for (Index = 0; Index < Len; Index++) {
|
|
StrBuf[Index] = L'*';
|
|
}
|
|
Label->Text = StrBuf;
|
|
Ret = PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
|
|
Label->Text = TmpPtr;
|
|
FreePool (StrBuf);
|
|
return Ret;
|
|
}
|
|
}
|
|
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
|
|
|
|
|
|
default:
|
|
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Hwnd, Msg, WParam, LParam);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
UI_EDIT_CLASS *
|
|
EFIAPI
|
|
GetEditClass (
|
|
VOID
|
|
)
|
|
{
|
|
if (CURRENT_CLASS != NULL) {
|
|
return CURRENT_CLASS;
|
|
}
|
|
|
|
InitUiClass ((UI_CONTROL_CLASS **)&CURRENT_CLASS, sizeof (*CURRENT_CLASS), L"UiEdit", (UI_CONTROL_CLASS *)GetLabelClass());
|
|
if (CURRENT_CLASS == NULL) {
|
|
return NULL;
|
|
}
|
|
((UI_CONTROL_CLASS *)CURRENT_CLASS)->WndProc = UiEditProc;
|
|
((UI_CONTROL_CLASS *)CURRENT_CLASS)->SetAttribute = UiEditSetAttribute;
|
|
//((UI_CONTROL_CLASS *)CURRENT_CLASS)->EstimateSize = UiEditEstimateSize;
|
|
|
|
return CURRENT_CLASS;
|
|
}
|
|
|