314 lines
7.6 KiB
C
314 lines
7.6 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"
|
|
|
|
STATIC UI_SCROLL_VIEW_CLASS *mScrollViewClass = NULL;
|
|
#define CURRENT_CLASS mScrollViewClass
|
|
|
|
VOID
|
|
UiScrollViewSetPosition (
|
|
UI_CONTROL *Control,
|
|
CONST RECT *Pos
|
|
)
|
|
{
|
|
UI_VERTICAL_LAYOUT *This;
|
|
UI_CONTROL *Item;
|
|
RECT Rc;
|
|
RECT ItemRc;
|
|
SIZE Size;
|
|
UINT32 Top;
|
|
UINT32 Expand;
|
|
SIZE Available;
|
|
SIZE ItemSize;
|
|
BOOLEAN EnableScroll;
|
|
INT32 ScrollBarWidth;
|
|
|
|
Size.cx = 0;
|
|
Size.cy = 0;
|
|
Expand = 0;
|
|
|
|
This = (UI_VERTICAL_LAYOUT *) Control;
|
|
|
|
ShowSetPositionDbgInfo (Control, Pos);
|
|
GetWindowRect(Control->Wnd, &Rc);
|
|
MapWindowPoints(HWND_DESKTOP, GetParent(Control->Wnd), (LPPOINT) &Rc, 2);
|
|
if (!EqualRect (&Rc, Pos)) {
|
|
ShowSetPositionDbgInfo (Control, Pos);
|
|
MoveWindow (Control->Wnd, Pos->left, Pos->top, Pos->right - Pos->left, Pos->bottom - Pos->top, TRUE);
|
|
CONTROL_CLASS_INVALIDATE (This);
|
|
Control->NeedUpdateChildPos = TRUE;
|
|
}
|
|
|
|
if (Control->ItemCount == 0) {
|
|
return ;
|
|
}
|
|
|
|
if ((GetWindowLongPtr (Control->Items[0]->Wnd, GWL_STYLE) & WS_VISIBLE) == 0) {
|
|
return ;
|
|
}
|
|
|
|
if (!Control->NeedUpdateChildPos) {
|
|
return ;
|
|
}
|
|
Control->NeedUpdateChildPos = FALSE;
|
|
|
|
|
|
CopyRect (&Rc, Pos);
|
|
OffsetRect (&Rc, -Rc.left, -Rc.top);
|
|
|
|
Rc.left += (GetControlPaddingLeft (Control) + GetControlBorderLeft (Control) );
|
|
Rc.top += (GetControlPaddingTop (Control) + GetControlBorderTop (Control) );
|
|
Rc.right -= (GetControlPaddingRight (Control) + GetControlBorderRight (Control) );
|
|
Rc.bottom -= (GetControlPaddingBottom (Control) + GetControlBorderBottom (Control));
|
|
|
|
if (Rc.left > Rc.right) {
|
|
Rc.left = Rc.right;
|
|
}
|
|
if (Rc.top > Rc.bottom) {
|
|
Rc.top = Rc.bottom;
|
|
}
|
|
|
|
Available.cx = Rc.right - Rc.left;
|
|
Available.cy = Rc.bottom - Rc.top;
|
|
|
|
Item = Control->Items[0];
|
|
|
|
|
|
Top = Rc.top;
|
|
EnableScroll = FALSE;
|
|
|
|
Item->Available = Available;
|
|
Size = CONTROL_CLASS (Item)->EstimateSize (Item, Available);
|
|
|
|
if (Size.cy == 0) {
|
|
ItemSize.cy = Available.cy;
|
|
} else if (Size.cy == MATCH_PARENT) {
|
|
ItemSize.cy = Rc.bottom - Top;
|
|
} else {
|
|
ItemSize.cy = Size.cy;
|
|
}
|
|
|
|
if ((Size.cx == 0) || (Size.cx == MATCH_PARENT)) {
|
|
ItemSize.cx = Available.cx;
|
|
} else {
|
|
ItemSize.cx = Size.cx;
|
|
}
|
|
|
|
if (Control->VScrollBar != NULL) {
|
|
if ((UINT32)ItemSize.cy > (UINT32) Available.cy) {
|
|
EnableScroll = TRUE;
|
|
}
|
|
}
|
|
|
|
if (Control->VScrollBar == NULL || !EnableScroll) {
|
|
ItemRc.left = Rc.left;
|
|
ItemRc.top = Top;
|
|
ItemRc.right = ItemRc.left + ItemSize.cx;
|
|
ItemRc.bottom = ItemRc.top + ItemSize.cy;
|
|
mSetPositionLevel++;
|
|
CONTROL_CLASS (Item)->SetPosition (Item, &ItemRc);
|
|
mSetPositionLevel--;
|
|
if (Control->VScrollBar != NULL) {
|
|
UiSetAttribute (Control->VScrollBar, L"visibility", L"false");
|
|
}
|
|
return ;
|
|
}
|
|
|
|
UiSetAttribute (Control->VScrollBar, L"visibility", L"true");
|
|
ScrollBarWidth = Control->VScrollBar->Control.Width.Value;
|
|
Available.cx -= ScrollBarWidth;
|
|
|
|
Item->Available = Available;
|
|
Size = CONTROL_CLASS (Item)->EstimateSize (Item, Available);
|
|
if (Size.cy == 0) {
|
|
ItemSize.cy = Available.cy;
|
|
} else if (Size.cy == MATCH_PARENT) {
|
|
ItemSize.cy = Rc.bottom - Top;
|
|
} else {
|
|
ItemSize.cy = Size.cy;
|
|
}
|
|
|
|
if ((Size.cx == 0) || (Size.cx == MATCH_PARENT)) {
|
|
ItemSize.cx = Available.cx;
|
|
} else {
|
|
ItemSize.cx = Size.cx;
|
|
}
|
|
|
|
Top -= Control->ScrollPos.y;
|
|
Control->VScrollBar->Range = ItemSize.cy - Available.cy;
|
|
|
|
//
|
|
// child item
|
|
//
|
|
ItemRc.left = Rc.left;
|
|
ItemRc.top = Top;
|
|
ItemRc.right = ItemRc.left + ItemSize.cx;
|
|
ItemRc.bottom = ItemRc.top + ItemSize.cy;
|
|
mSetPositionLevel++;
|
|
CONTROL_CLASS (Item)->SetPosition (Item, &ItemRc);
|
|
mSetPositionLevel--;
|
|
|
|
//
|
|
// scrollbar
|
|
//
|
|
ItemRc.left = Rc.right - ScrollBarWidth;
|
|
ItemRc.top = 0;
|
|
ItemRc.right = ItemRc.left + ScrollBarWidth;
|
|
ItemRc.bottom = Rc.bottom;
|
|
CONTROL_CLASS (Control->VScrollBar)->SetPosition ((UI_CONTROL *)Control->VScrollBar, &ItemRc);
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
EFIAPI
|
|
UiScrollViewSetAttribute (
|
|
UI_CONTROL *Control,
|
|
CHAR16 *Name,
|
|
CHAR16 *Value
|
|
)
|
|
{
|
|
|
|
UI_SCROLL_VIEW *This;
|
|
|
|
This = (UI_SCROLL_VIEW *) Control;
|
|
|
|
if (StrCmp (Name, L"scrollbarThumbVertical") == 0) {
|
|
if (Control->VScrollBar != NULL) {
|
|
UiSetAttribute (Control->VScrollBar, L"thumb", Value);
|
|
}
|
|
} else if (StrCmp (Name, L"scrollbarTrackVertical") == 0) {
|
|
if (Control->VScrollBar != NULL) {
|
|
UiSetAttribute (Control->VScrollBar, L"track", Value);
|
|
}
|
|
} else {
|
|
return PARENT_CLASS_SET_ATTRIBUTE (CURRENT_CLASS, Control, Name, Value);
|
|
}
|
|
|
|
CONTROL_CLASS_INVALIDATE (This);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
LRESULT
|
|
EFIAPI
|
|
UiScrollViewKeyDown (
|
|
UI_SCROLL_VIEW *This,
|
|
WPARAM WParam,
|
|
LPARAM LParam
|
|
)
|
|
{
|
|
UI_CONTROL *Control;
|
|
UI_SCROLLBAR *VScrollBar;
|
|
|
|
Control = (UI_CONTROL *) This;
|
|
VScrollBar = Control->VScrollBar;
|
|
|
|
switch (WParam) {
|
|
|
|
case VK_DOWN:
|
|
SCROLLBAR_CLASS(VScrollBar)->SetScrollPos (VScrollBar, VScrollBar->ScrollPos + VScrollBar->LineSize);
|
|
break;
|
|
|
|
case VK_UP:
|
|
SCROLLBAR_CLASS(VScrollBar)->SetScrollPos (VScrollBar, VScrollBar->ScrollPos - VScrollBar->LineSize);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
LRESULT
|
|
EFIAPI
|
|
UiScrollViewProc (
|
|
HWND Wnd,
|
|
UINT32 Msg,
|
|
WPARAM WParam,
|
|
LPARAM LParam
|
|
)
|
|
{
|
|
UI_SCROLL_VIEW *This;
|
|
UI_CONTROL *Control;
|
|
|
|
This = (UI_SCROLL_VIEW *) GetWindowLongPtr (Wnd, 0);
|
|
if (This == NULL && Msg != WM_CREATE && Msg != WM_NCCALCSIZE) {
|
|
ASSERT (FALSE);
|
|
return 0;
|
|
}
|
|
Control = (UI_CONTROL *)This;
|
|
|
|
switch (Msg) {
|
|
|
|
case WM_CREATE:
|
|
This = (UI_SCROLL_VIEW *) AllocateZeroPool (sizeof (*CURRENT_CLASS));
|
|
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);
|
|
SetWindowLongPtr (
|
|
Control->Wnd,
|
|
GWL_EXSTYLE, GetWindowLongPtr (Control->Wnd, GWL_EXSTYLE) & ~WS_EX_NOACTIVATE
|
|
);
|
|
UiSetAttribute (Control, L"tabstop", L"true");
|
|
break;
|
|
|
|
case WM_NCHITTEST:
|
|
if (Control->VScrollBar != NULL) {
|
|
return HTCLIENT;
|
|
}
|
|
return HTTRANSPARENT;
|
|
|
|
case WM_KEYDOWN:
|
|
UiScrollViewKeyDown (This, WParam, LParam);
|
|
break;
|
|
|
|
default:
|
|
return PARENT_CLASS_WNDPROC (CURRENT_CLASS, Wnd, Msg, WParam, LParam);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
UI_SCROLL_VIEW_CLASS *
|
|
EFIAPI
|
|
GetScrollViewClass (
|
|
VOID
|
|
)
|
|
{
|
|
if (CURRENT_CLASS != NULL) {
|
|
return CURRENT_CLASS;
|
|
}
|
|
|
|
InitUiClass ((UI_CONTROL_CLASS **)&CURRENT_CLASS, sizeof (*CURRENT_CLASS), L"ScrollView", (UI_CONTROL_CLASS *)GetControlClass());
|
|
if (CURRENT_CLASS == NULL) {
|
|
return NULL;
|
|
}
|
|
((UI_CONTROL_CLASS *)CURRENT_CLASS)->WndProc = UiScrollViewProc;
|
|
((UI_CONTROL_CLASS *)CURRENT_CLASS)->SetAttribute = UiScrollViewSetAttribute;
|
|
((UI_CONTROL_CLASS *)CURRENT_CLASS)->SetPosition = UiScrollViewSetPosition;
|
|
|
|
return CURRENT_CLASS;
|
|
}
|
|
|