411 lines
11 KiB
C
411 lines
11 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 "H2ODisplayEngineLocalMetro.h"
|
|
#include <Library/UefiLib.h>
|
|
#include "UiControls.h"
|
|
|
|
STATIC UI_SCROLLBAR_CLASS *mScrollBarClass = NULL;
|
|
#define CURRENT_CLASS mScrollBarClass
|
|
|
|
#define SCROLLBAR_TIMER_ID 1
|
|
|
|
#if FixedPcdGet32(PcdH2OLmdeMultiLayout) == 0
|
|
CHAR16 *mScrollbarChilds = L""
|
|
L"<Texture float='true' name='bkg' width='match_parent' height='match_parent' background-color='0x50101010' background-image-style='stretch'/>"
|
|
L"<HorizontalLayout float='true' height='match_parent' background-color='0x0'>"
|
|
L"<HorizontalLayout/>"
|
|
L"<Texture name='track' width='1' background-color='0x0' background-image-style='stretch'/>"
|
|
L"<HorizontalLayout/>"
|
|
L"</HorizontalLayout>"
|
|
L"<HorizontalLayout float='true' height='match_parent' name='thumbparent'>"
|
|
L"<HorizontalLayout/>"
|
|
L"<Texture name='thumb' width='19' background-color='0xA0F0F0F0' background-image-style='stretch' visibility='false'/>"
|
|
L"<HorizontalLayout/>"
|
|
L"</HorizontalLayout>"
|
|
L"";
|
|
#endif
|
|
|
|
VOID
|
|
EFIAPI
|
|
UiScrollBarSetPosition (
|
|
UI_CONTROL *Control,
|
|
CONST RECT *Pos
|
|
)
|
|
{
|
|
UI_SCROLLBAR *This;
|
|
INT32 Cy;
|
|
INT32 ThumbY;
|
|
UI_CONTROL *Thumb;
|
|
RECT Rc;
|
|
INT32 MinThumbY;
|
|
UI_CONTROL *ThumbParent;
|
|
CHAR16 Str[20];
|
|
|
|
This = (UI_SCROLLBAR *) Control;
|
|
|
|
CopyRect (&Rc, Pos);
|
|
OffsetRect (&Rc, -Rc.left, -Rc.top);
|
|
|
|
Cy = Rc.bottom - Rc.top;
|
|
//ThumbY = Cy * (Rc.bottom - Rc.top) / (This->Range + Rc.bottom - Rc.top);
|
|
MinThumbY = 26;
|
|
This->LineSize = This->Range / (Cy - MinThumbY) + 1;
|
|
if ((Cy - MinThumbY) <= (This->Range / This->LineSize)) {
|
|
ThumbY = MinThumbY;
|
|
This->LineSize = This->Range / (Cy - ThumbY) + 1;
|
|
} else {
|
|
ThumbY = Cy - (This->Range / This->LineSize);
|
|
}
|
|
|
|
if (This->Range == 0) {
|
|
This->Thumb.left = Rc.left;
|
|
This->Thumb.right = Rc.right;
|
|
This->Thumb.top = 0;
|
|
This->Thumb.bottom = Cy;
|
|
} else {
|
|
This->Thumb.left = Rc.left;
|
|
This->Thumb.right = Rc.right;
|
|
This->Thumb.top = This->ScrollPos * (Cy - ThumbY) / (This->Range / This->LineSize);
|
|
This->Thumb.bottom = This->Thumb.top + ThumbY;
|
|
}
|
|
|
|
Thumb = UiFindChildByName (This, L"thumb");
|
|
if (Thumb != NULL) {
|
|
ThumbParent = UiFindChildByName (This, L"thumbparent");
|
|
UnicodeSPrint (Str, sizeof (Str), L"%dpx", This->Thumb.top);
|
|
UiSetAttribute (ThumbParent, L"padding-top", Str);
|
|
UnicodeSPrint (Str, sizeof (Str), L"%dpx", Rc.bottom - This->Thumb.bottom);
|
|
UiSetAttribute (ThumbParent, L"padding-bottom", Str);
|
|
if (This->Thumb.top == 0 && This->Thumb.bottom == Rc.bottom) {
|
|
UiSetAttribute (Thumb, L"visibility", L"false");
|
|
} else {
|
|
UiSetAttribute (Thumb, L"visibility", L"true");
|
|
}
|
|
}
|
|
|
|
SetWindowPos (Control->Wnd, HWND_TOP, Pos->left, Pos->top, Pos->right - Pos->left, Pos->bottom - Pos->top, 0);
|
|
PARENT_CONTROL_CLASS(CURRENT_CLASS)->SetPosition (Control,Pos);
|
|
}
|
|
|
|
|
|
VOID
|
|
EFIAPI
|
|
UiScrollBarSetScrollPos (
|
|
UI_SCROLLBAR *This,
|
|
INT32 Pos
|
|
)
|
|
{
|
|
RECT Rc;
|
|
INT32 ScrollPos;
|
|
|
|
if (This->ScrollPos == Pos) {
|
|
return ;
|
|
}
|
|
|
|
if (Pos < 0) {
|
|
if (This->ScrollPos == 0) {
|
|
return ;
|
|
}
|
|
Pos = 0;
|
|
}
|
|
|
|
GetClientRect (This->Control.Wnd, &Rc);
|
|
if ((Pos + (This->Thumb.bottom - This->Thumb.top)) > Rc.bottom) {
|
|
ScrollPos = Rc.bottom - (This->Thumb.bottom - This->Thumb.top);
|
|
if (ScrollPos == This->ScrollPos) {
|
|
return ;
|
|
}
|
|
This->ScrollPos = ScrollPos;
|
|
if (This->Owner != NULL) {
|
|
This->Owner->ScrollPos.y = This->Range;
|
|
}
|
|
} else {
|
|
This->ScrollPos = Pos;
|
|
if (This->Owner != NULL) {
|
|
This->Owner->ScrollPos.y = This->ScrollPos * This->LineSize;
|
|
}
|
|
}
|
|
|
|
if (This->Owner != NULL) {
|
|
UiNeedUpdatePos (This->Owner);
|
|
This->Owner->Class->Invalidate (This->Owner);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
UiScrollBarCreate (
|
|
UI_SCROLLBAR *This
|
|
)
|
|
{
|
|
This->Owner = NULL;
|
|
This->Horizontal = FALSE;
|
|
|
|
This->Range = 19;
|
|
This->LineSize = 1;
|
|
This->ScrollPos = 0;
|
|
This->LastScrollPos = 0;
|
|
This->LastScrollOffset = 0;
|
|
This->ScrollRepeatDelay = 0;
|
|
|
|
This->LastMouse.x = 0;
|
|
This->LastMouse.y = 0;
|
|
|
|
This->ShowThumb = TRUE;
|
|
}
|
|
|
|
VOID
|
|
UiScrollBarSetHorizontal (
|
|
UI_SCROLLBAR *This,
|
|
BOOLEAN IsHor
|
|
)
|
|
{
|
|
|
|
UI_CONTROL *Control;
|
|
|
|
Control = (UI_CONTROL *) This;
|
|
|
|
This->Horizontal = IsHor;
|
|
|
|
if (IsHor) {
|
|
This->Horizontal = IsHor;
|
|
if (!IS_CONTROL_HEIGHT_DEFINED (Control)) {
|
|
UiSetAttribute (Control, L"width" , L"0");
|
|
UiSetAttribute (Control, L"height", L"20");
|
|
}
|
|
} else {
|
|
if (!IS_CONTROL_WIDTH_DEFINED (Control)) {
|
|
UiSetAttribute (Control, L"width" , L"25");
|
|
UiSetAttribute (Control, L"height", L"0");
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOLEAN
|
|
EFIAPI
|
|
UiScrollBarSetAttribute (
|
|
UI_CONTROL *Control,
|
|
CHAR16 *Name,
|
|
CHAR16 *Value
|
|
)
|
|
{
|
|
|
|
|
|
UI_SCROLLBAR *This;
|
|
UI_CONTROL *Child;
|
|
This = (UI_SCROLLBAR *) Control;
|
|
|
|
if (StrCmp (Name, L"thumb") == 0) {
|
|
Child = UiFindChildByName (This, L"thumb");
|
|
UiApplyAttributeList (Child, Value);
|
|
} else if (StrCmp (Name, L"track") == 0) {
|
|
Child = UiFindChildByName (This, L"track");
|
|
UiApplyAttributeList (Child, Value);
|
|
} else if (StrCmp (Name, L"hor") == 0) {
|
|
UiScrollBarSetHorizontal (This, (StrCmp (Value, L"true") == 0));
|
|
} else if (StrCmp (Name, L"displayscrollbar") == 0) {
|
|
if (StrCmp (Value, L"true") == 0) {
|
|
UiScrollBarSetHorizontal (This, This->Horizontal);
|
|
} else {
|
|
UiSetAttribute (Control, L"width" , L"0");
|
|
UiSetAttribute (Control, L"height", L"0");
|
|
}
|
|
} else {
|
|
return PARENT_CLASS_SET_ATTRIBUTE (CURRENT_CLASS, Control, Name, Value);
|
|
}
|
|
|
|
CONTROL_CLASS_INVALIDATE (This);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT
|
|
EFIAPI
|
|
UiScrollBarProc (
|
|
HWND Wnd,
|
|
UINT32 Msg,
|
|
WPARAM WParam,
|
|
LPARAM LParam
|
|
)
|
|
{
|
|
UI_SCROLLBAR *This;
|
|
UI_CONTROL *Control;
|
|
POINT Point;
|
|
RECT Rc;
|
|
|
|
Control = (UI_CONTROL *) GetWindowLongPtr (Wnd, 0);
|
|
if (Control == NULL && Msg != WM_CREATE && Msg != WM_NCCALCSIZE) {
|
|
ASSERT (FALSE);
|
|
return 0;
|
|
}
|
|
This = (UI_SCROLLBAR *) Control;
|
|
|
|
switch (Msg) {
|
|
|
|
case WM_CREATE:
|
|
This = (UI_SCROLLBAR *) AllocateZeroPool (sizeof (UI_SCROLLBAR));
|
|
if (This != NULL) {
|
|
CONTROL_CLASS (This) = (UI_CONTROL_CLASS *) GetClassLongPtr (Wnd, 0);
|
|
SetWindowLongPtr (Wnd, 0, (INTN)This);
|
|
SendMessage (Wnd, UI_NOTIFY_CREATE, WParam, LParam);
|
|
}
|
|
break;
|
|
|
|
case UI_NOTIFY_CREATE:
|
|
PARENT_CLASS_WNDPROC (CURRENT_CLASS, Wnd, Msg, WParam, LParam);
|
|
UiScrollBarCreate (This);
|
|
XmlCreateControl (mScrollbarChilds, Control);
|
|
break;
|
|
|
|
case UI_NOTIFY_PAINT:
|
|
if (WParam == PAINT_ALL) {
|
|
return PARENT_CLASS_WNDPROC(CURRENT_CLASS, Wnd, Msg, WParam, LParam);
|
|
}
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
POINTSTOPOINT(Point, LParam);
|
|
if (This->Range == 0) {
|
|
break;
|
|
}
|
|
if (PtInRect (&This->Thumb, Point)) {
|
|
This->ThumbState |= (UINTN) UISTATE_CAPTURED | UISTATE_PRESSED;
|
|
ClientToScreen (Wnd, &Point);
|
|
This->LastMouse = Point;
|
|
This->LastScrollPos = This->ScrollPos;
|
|
} else {
|
|
if (Point.y < This->Thumb.top) {
|
|
UiScrollBarSetScrollPos (This, This->ScrollPos - This->LineSize);
|
|
} else if (Point.y > This->Thumb.bottom) {
|
|
UiScrollBarSetScrollPos (This, This->ScrollPos + This->LineSize);
|
|
}
|
|
}
|
|
if (GetCapture () != Wnd) {
|
|
SetCapture (Wnd);
|
|
This->ScrollRepeatDelay = 0;
|
|
SetTimer (Wnd, SCROLLBAR_TIMER_ID, 50, NULL);
|
|
Control->Class->Invalidate (Control);
|
|
}
|
|
break;
|
|
|
|
case WM_LBUTTONUP:
|
|
case WM_NCLBUTTONUP:
|
|
if (GetCapture () == Wnd) {
|
|
ReleaseCapture();
|
|
KillTimer (Wnd, SCROLLBAR_TIMER_ID);
|
|
if ((This->ThumbState & UISTATE_CAPTURED) != 0) {
|
|
This->ThumbState &= ~((UINTN) UISTATE_CAPTURED | UISTATE_PRESSED );
|
|
Control->Class->Invalidate (Control);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
++This->ScrollRepeatDelay;
|
|
if ((This->ThumbState & UISTATE_CAPTURED) == 0) {
|
|
if (This->ScrollRepeatDelay < 5) {
|
|
break;
|
|
}
|
|
GetCursorPos (&Point);
|
|
ScreenToClient (Wnd, &Point);
|
|
|
|
if (Point.y < This->Thumb.top) {
|
|
UiScrollBarSetScrollPos (This, This->ScrollPos - This->LineSize);
|
|
} else if (Point.y > This->Thumb.bottom) {
|
|
UiScrollBarSetScrollPos (This, This->ScrollPos + This->LineSize);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case WM_MOUSEMOVE:
|
|
case WM_NCMOUSEMOVE:
|
|
POINTSTOPOINT(Point, LParam);
|
|
GetClientRect (Wnd, &Rc);
|
|
if (Msg == WM_MOUSEMOVE) {
|
|
ClientToScreen (Wnd, &Point);
|
|
}
|
|
|
|
if ((This->ThumbState & UISTATE_CAPTURED) != 0 && This->Range != 0) {
|
|
if (This->Horizontal) {
|
|
This->LastScrollOffset = (Point.x - This->LastMouse.x) * This->Range / (Rc.right - Rc.left - This->Thumb.right + This->Thumb.left - 2 * Control->Height.Value);
|
|
} else {
|
|
This->LastScrollOffset = (Point.y - This->LastMouse.y) * (This->Range / This->LineSize) / (Rc.bottom - Rc.top - This->Thumb.bottom + This->Thumb.top);
|
|
}
|
|
UiScrollBarSetScrollPos (This, This->LastScrollPos + This->LastScrollOffset);
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_MOUSEENTER:
|
|
POINTSTOPOINT(Point, LParam);
|
|
ScreenToClient (Wnd, &Point);
|
|
// This->Button1State |= UISTATE_HOVER;
|
|
// This->Button2State |= UISTATE_HOVER;
|
|
// if(PtInRect(&This->Thumb, Point) ) {
|
|
This->ThumbState |= (UINTN) UISTATE_HOVER;
|
|
// }
|
|
Control->Class->Invalidate (Control);
|
|
break;
|
|
|
|
|
|
case WM_MOUSELEAVE:
|
|
// This->Button1State &= ~UISTATE_HOVER;
|
|
// This->Button2State &= ~UISTATE_HOVER;
|
|
KillTimer (Wnd, SCROLLBAR_TIMER_ID);
|
|
if ((This->ThumbState & UISTATE_CAPTURED) != 0) {
|
|
This->ThumbState &= ~((UINTN) UISTATE_CAPTURED | UISTATE_PRESSED );
|
|
}
|
|
|
|
This->ThumbState &= ~(UINTN) UISTATE_HOVER;
|
|
Control->Class->Invalidate (Control);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
KillTimer (Wnd, SCROLLBAR_TIMER_ID);
|
|
return PARENT_CLASS_WNDPROC(CURRENT_CLASS, Wnd, Msg, WParam, LParam);
|
|
|
|
case WM_NCHITTEST:
|
|
return HTCLIENT;
|
|
|
|
default:
|
|
return PARENT_CLASS_WNDPROC(CURRENT_CLASS, Wnd, Msg, WParam, LParam);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
UI_SCROLLBAR_CLASS *
|
|
EFIAPI
|
|
GetScrollBarClass (
|
|
VOID
|
|
)
|
|
{
|
|
if (CURRENT_CLASS != NULL) {
|
|
return CURRENT_CLASS;
|
|
}
|
|
|
|
InitUiClass ((UI_CONTROL_CLASS **)&CURRENT_CLASS, sizeof (*CURRENT_CLASS), L"ScrollBar", (UI_CONTROL_CLASS *)GetControlClass());
|
|
if (CURRENT_CLASS == NULL) {
|
|
return NULL;
|
|
}
|
|
((UI_CONTROL_CLASS *)CURRENT_CLASS)->WndProc = UiScrollBarProc;
|
|
((UI_CONTROL_CLASS *)CURRENT_CLASS)->SetAttribute = UiScrollBarSetAttribute;
|
|
((UI_CONTROL_CLASS *)CURRENT_CLASS)->SetPosition = UiScrollBarSetPosition;
|
|
|
|
CURRENT_CLASS->SetScrollPos = UiScrollBarSetScrollPos;
|
|
|
|
return CURRENT_CLASS;
|
|
}
|
|
|