third-party libs
This commit is contained in:
parent
f836927d3a
commit
b154ee9266
3667 changed files with 854591 additions and 0 deletions
474
third-party/BugTrap-1.3-57bd515/source/Splitter.cpp
vendored
Normal file
474
third-party/BugTrap-1.3-57bd515/source/Splitter.cpp
vendored
Normal file
|
|
@ -0,0 +1,474 @@
|
|||
/*
|
||||
* This is a part of the BugTrap package.
|
||||
* Copyright (c) 2005-2009 IntelleSoft.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Description: Splitter control class.
|
||||
* Author: Maksim Pyatkovskiy.
|
||||
*
|
||||
* This source code is only intended as a supplement to the
|
||||
* BugTrap package reference and related electronic documentation
|
||||
* provided with the product. See these sources for detailed
|
||||
* information regarding the BugTrap package.
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "Splitter.h"
|
||||
#include "BugTrapUtils.h"
|
||||
#include "Globals.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @param eDirection - splitter direction.
|
||||
* @param bProportionalMode - proportional mode.
|
||||
*/
|
||||
CSplitter::CSplitter(SPLITTER_DIRECTION eDirection, bool bProportionalMode)
|
||||
{
|
||||
ClearPanels();
|
||||
m_pfnOldSplitterWndProc = NULL;
|
||||
m_bProportionalMode = bProportionalMode;
|
||||
SetDirection(eDirection);
|
||||
m_nSplitterSize = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param eDirection - new splitter direction.
|
||||
*/
|
||||
void CSplitter::SetDirection(SPLITTER_DIRECTION eDirection)
|
||||
{
|
||||
m_eDirection = eDirection;
|
||||
if (m_hwnd)
|
||||
ResetSplitterPos();
|
||||
else
|
||||
ClearSplitterPos();
|
||||
}
|
||||
|
||||
void CSplitter::ResetSplitterPos(void)
|
||||
{
|
||||
_ASSERTE(m_hwnd != NULL);
|
||||
m_nSplitterSize = CalcSplitterSize();
|
||||
m_nSplitterPos = m_nIdealPos = m_nSplitterSize / 2;
|
||||
UpdateLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rect - splitter bar coordinates.
|
||||
*/
|
||||
void CSplitter::GetSplitterBarRect(RECT& rect) const
|
||||
{
|
||||
_ASSERTE(m_hwnd != NULL);
|
||||
GetClientRect(m_hwnd, &rect);
|
||||
int nBarSize = GetSystemMetrics(m_eDirection == SD_VERTICAL ? SM_CYFRAME : SM_CXFRAME);
|
||||
int nSplitterBarEnd = m_nSplitterPos + nBarSize;
|
||||
if (m_eDirection == SD_VERTICAL)
|
||||
{
|
||||
rect.top = m_nSplitterPos;
|
||||
if (rect.bottom > nSplitterBarEnd)
|
||||
rect.bottom = nSplitterBarEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.left = m_nSplitterPos;
|
||||
if (rect.right > nSplitterBarEnd)
|
||||
rect.right = nSplitterBarEnd;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param point - point coordinates.
|
||||
* @return true if point appears in boundaries of Splitter text.
|
||||
*/
|
||||
BOOL CSplitter::HitTest(const POINT& point) const
|
||||
{
|
||||
_ASSERTE(m_hwnd != NULL);
|
||||
RECT rect;
|
||||
GetSplitterBarRect(rect);
|
||||
return PtInRect(&rect, point);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x - point x-coordinate.
|
||||
* @param y - point y-coordinate.
|
||||
* @return true if point appears in boundaries of Splitter text.
|
||||
*/
|
||||
BOOL CSplitter::HitTest(int x, int y) const
|
||||
{
|
||||
POINT point;
|
||||
point.x = x;
|
||||
point.y = y;
|
||||
return HitTest(point);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hdc - drawing context.
|
||||
* @param iPanel - panel number.
|
||||
* @return true if panel index is valid.
|
||||
*/
|
||||
BOOL CSplitter::DrawPanel(HDC hdc, int iPanel) const
|
||||
{
|
||||
_ASSERTE(m_hwnd != NULL);
|
||||
_ASSERTE(g_pResManager != NULL);
|
||||
if (iPanel >= 0 && iPanel < NUM_PANELS)
|
||||
{
|
||||
RECT rect;
|
||||
CalcPanelRect(iPanel, rect, false);
|
||||
HWND hwndPanel = m_arrPanels[iPanel];
|
||||
if (hwndPanel == NULL || (GetWindowLong(hwndPanel, GWL_EXSTYLE) & WS_EX_CLIENTEDGE) == 0)
|
||||
{
|
||||
int nCXEdge = GetSystemMetrics(SM_CXEDGE) * 2;
|
||||
int nCYEdge = GetSystemMetrics(SM_CYEDGE) * 2;
|
||||
if (rect.right - rect.left >= nCXEdge && rect.bottom - rect.top >= nCYEdge)
|
||||
DrawEdge(hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
|
||||
}
|
||||
if (hwndPanel == NULL)
|
||||
FillRect(hdc, &rect, g_pResManager->m_hbrAppWorkspace);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hdc - drawing context.
|
||||
*/
|
||||
void CSplitter::DrawSplitter(HDC hdc) const
|
||||
{
|
||||
_ASSERTE(m_hwnd != NULL);
|
||||
DrawSplitterBar(hdc);
|
||||
DrawPanel(hdc, 0);
|
||||
DrawPanel(hdc, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hdc - drawing context.
|
||||
*/
|
||||
void CSplitter::DrawSplitterBar(HDC hdc) const
|
||||
{
|
||||
_ASSERTE(m_hwnd != NULL);
|
||||
RECT rect;
|
||||
GetSplitterBarRect(rect);
|
||||
_ASSERTE(g_pResManager != NULL);
|
||||
FillRect(hdc, &rect, g_pResManager->m_hbrButtonFaceBrush);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param iPanel - panel number.
|
||||
* @param hwndPanel - panel window handle.
|
||||
* @return true if panel index is valid.
|
||||
*/
|
||||
BOOL CSplitter::SetPanel(int iPanel, HWND hwndPanel)
|
||||
{
|
||||
_ASSERTE(m_hwnd != NULL);
|
||||
if (iPanel >= 0 && iPanel < NUM_PANELS)
|
||||
{
|
||||
m_arrPanels[iPanel] = hwndPanel;
|
||||
if (hwndPanel)
|
||||
{
|
||||
RECT rect;
|
||||
CalcPanelRect(iPanel, rect, true);
|
||||
HWND hwndPanelParent = GetParent(hwndPanel);
|
||||
MapWindowRect(m_hwnd, hwndPanelParent, &rect);
|
||||
SetWindowPos(hwndPanel, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param iPanel - panel number.
|
||||
* @param rect - panel rectangle.
|
||||
* @param bShrinkRect - true if rectangle must be shrinked.
|
||||
* @return true if panel index is valid.
|
||||
*/
|
||||
BOOL CSplitter::CalcPanelRect(int iPanel, RECT& rect, bool bShrinkRect) const
|
||||
{
|
||||
_ASSERTE(m_hwnd != NULL);
|
||||
if (iPanel >= 0 && iPanel < NUM_PANELS)
|
||||
{
|
||||
GetClientRect(m_hwnd, &rect);
|
||||
if (m_eDirection == SD_VERTICAL)
|
||||
{
|
||||
if (iPanel == 0)
|
||||
rect.bottom = m_nSplitterPos;
|
||||
else
|
||||
{
|
||||
int nBarSize = GetSystemMetrics(SM_CYFRAME);
|
||||
int nSplitterBarEnd = m_nSplitterPos + nBarSize;
|
||||
rect.top = rect.bottom > nSplitterBarEnd ? nSplitterBarEnd : rect.bottom;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iPanel == 0)
|
||||
rect.right = m_nSplitterPos;
|
||||
else
|
||||
{
|
||||
int nBarSize = GetSystemMetrics(SM_CXFRAME);
|
||||
int nSplitterBarEnd = m_nSplitterPos + nBarSize;
|
||||
rect.left = rect.right > nSplitterBarEnd ? nSplitterBarEnd : rect.right;
|
||||
}
|
||||
}
|
||||
if (bShrinkRect)
|
||||
{
|
||||
HWND hwndPanel = m_arrPanels[iPanel];
|
||||
if (hwndPanel == NULL || (GetWindowLong(hwndPanel, GWL_EXSTYLE) & WS_EX_CLIENTEDGE) == 0)
|
||||
{
|
||||
int nCXEdge = GetSystemMetrics(SM_CXEDGE);
|
||||
int nCYEdge = GetSystemMetrics(SM_CYEDGE);
|
||||
if (rect.right - rect.left >= nCXEdge * 2)
|
||||
{
|
||||
rect.left += nCXEdge;
|
||||
rect.right -= nCXEdge;
|
||||
}
|
||||
if (rect.bottom - rect.top >= nCYEdge * 2)
|
||||
{
|
||||
rect.top += nCYEdge;
|
||||
rect.bottom -= nCYEdge;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CSplitter::UpdateLayout(void)
|
||||
{
|
||||
_ASSERTE(m_hwnd != NULL);
|
||||
InvalidateRect(m_hwnd, NULL, FALSE);
|
||||
HDWP hdwp = BeginDeferWindowPos(NUM_PANELS);
|
||||
if (hdwp)
|
||||
{
|
||||
for (int iPanel = 0; iPanel < NUM_PANELS; ++iPanel)
|
||||
{
|
||||
HWND hwndPanel = m_arrPanels[iPanel];
|
||||
if (hwndPanel)
|
||||
{
|
||||
RECT rect;
|
||||
CalcPanelRect(iPanel, rect, true);
|
||||
HWND hwndPanelParent = GetParent(hwndPanel);
|
||||
MapWindowRect(m_hwnd, hwndPanelParent, &rect);
|
||||
DeferWindowPos(hdwp, hwndPanel, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
EndDeferWindowPos(hdwp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nSplitterSize - new splitter size.
|
||||
*/
|
||||
void CSplitter::ResizeSplitter(int nSplitterSize)
|
||||
{
|
||||
int nEdgeType, nFrameType;
|
||||
if (m_eDirection == SD_VERTICAL)
|
||||
{
|
||||
nEdgeType = SM_CYEDGE;
|
||||
nFrameType = SM_CYFRAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
nEdgeType = SM_CXEDGE;
|
||||
nFrameType = SM_CXFRAME;
|
||||
}
|
||||
int nBarSize = GetSystemMetrics(nFrameType);
|
||||
int nEdgeSize = GetSystemMetrics(nEdgeType) * 2;
|
||||
nSplitterSize -= nBarSize;
|
||||
nSplitterSize -= nEdgeSize;
|
||||
if (nSplitterSize < 0)
|
||||
nSplitterSize = 0;
|
||||
if (m_bProportionalMode)
|
||||
m_nSplitterPos = m_nSplitterSize > 0 ? MulDiv(m_nIdealPos, nSplitterSize, m_nSplitterSize) : nSplitterSize / 2;
|
||||
if (m_nSplitterPos < nEdgeSize)
|
||||
m_nSplitterPos = nEdgeSize;
|
||||
if (m_nSplitterPos > nSplitterSize)
|
||||
m_nSplitterPos = nSplitterSize;
|
||||
UpdateLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nSplitterPos - new splitter position.
|
||||
*/
|
||||
void CSplitter::SetSplitterPos(int nSplitterPos)
|
||||
{
|
||||
_ASSERTE(m_hwnd != NULL);
|
||||
int nEdgeSize = GetSystemMetrics(m_eDirection == SD_VERTICAL ? SM_CYEDGE : SM_CXEDGE) * 2;
|
||||
int nSplitterSize = CalcSplitterSize();
|
||||
if (nSplitterPos < nEdgeSize)
|
||||
nSplitterPos = nEdgeSize;
|
||||
if (nSplitterPos > nSplitterSize)
|
||||
nSplitterPos = nSplitterSize;
|
||||
if (m_nSplitterPos != nSplitterPos)
|
||||
{
|
||||
m_nSplitterSize = nSplitterSize;
|
||||
m_nIdealPos = m_nSplitterPos = nSplitterPos;
|
||||
UpdateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hwnd - window handle.
|
||||
* @param uMsg - message identifier.
|
||||
* @param wParam - first message parameter.
|
||||
* @param lParam - second message parameter.
|
||||
*/
|
||||
LRESULT CALLBACK CSplitter::SplitterWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int x, y, nSplitterPos, nSplitterSize;
|
||||
POINT point;
|
||||
HCURSOR hCursor;
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc;
|
||||
DWORD dwResult;
|
||||
|
||||
CSplitter* _this = (CSplitter*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
_ASSERTE(_this != NULL);
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_NCHITTEST:
|
||||
if (GetCapture() == hwnd)
|
||||
return HTCLIENT;
|
||||
point.x = GET_X_LPARAM(lParam);
|
||||
point.y = GET_Y_LPARAM(lParam);
|
||||
ScreenToClient(hwnd, &point);
|
||||
return (_this->HitTest(point) ? HTCLIENT : HTTRANSPARENT);
|
||||
case WM_SETCURSOR:
|
||||
_ASSERTE(g_pResManager != NULL);
|
||||
dwResult = GetMessagePos();
|
||||
point.x = GET_X_LPARAM(dwResult);
|
||||
point.y = GET_Y_LPARAM(dwResult);
|
||||
ScreenToClient(hwnd, &point);
|
||||
if (_this->HitTest(point))
|
||||
hCursor = _this->m_eDirection == SD_VERTICAL ? g_pResManager->m_hUpDownCursor : g_pResManager->m_hLeftRightCursor;
|
||||
else
|
||||
hCursor = g_pResManager->m_hArrowCursor;
|
||||
if (hCursor)
|
||||
{
|
||||
SetCursor(hCursor);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
case WM_LBUTTONDOWN:
|
||||
if (GetCapture() != hwnd)
|
||||
{
|
||||
x = GET_X_LPARAM(lParam);
|
||||
y = GET_Y_LPARAM(lParam);
|
||||
if (_this->HitTest(x, y))
|
||||
SetCapture(hwnd);
|
||||
}
|
||||
return 0;
|
||||
case WM_MOUSEMOVE:
|
||||
if (GetCapture() == hwnd)
|
||||
{
|
||||
nSplitterPos = _this->m_eDirection == SD_VERTICAL ? GET_Y_LPARAM(lParam) : GET_X_LPARAM(lParam);
|
||||
_this->SetSplitterPos(nSplitterPos);
|
||||
}
|
||||
return 0;
|
||||
case WM_LBUTTONUP:
|
||||
if (GetCapture() == hwnd)
|
||||
ReleaseCapture();
|
||||
return 0;
|
||||
case WM_CAPTURECHANGED:
|
||||
return 0;
|
||||
case WM_ERASEBKGND:
|
||||
return TRUE;
|
||||
case WM_SIZE:
|
||||
nSplitterSize = _this->m_eDirection == SD_VERTICAL ? GET_Y_LPARAM(lParam) : GET_X_LPARAM(lParam);
|
||||
_this->ResizeSplitter(nSplitterSize);
|
||||
return 0;
|
||||
case WM_PAINT:
|
||||
hdc = (HDC)wParam;
|
||||
if (! hdc)
|
||||
{
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
if (hdc)
|
||||
{
|
||||
_this->DrawSplitter(hdc);
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
}
|
||||
else
|
||||
_this->DrawSplitter(hdc);
|
||||
return 0;
|
||||
case WM_PRINTCLIENT:
|
||||
hdc = (HDC)wParam;
|
||||
_this->DrawSplitter(hdc);
|
||||
return 0;
|
||||
case WM_GETDLGCODE:
|
||||
return DLGC_STATIC;
|
||||
default:
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hwnd - splitter window handle.
|
||||
*/
|
||||
void CSplitter::Attach(HWND hwnd)
|
||||
{
|
||||
_ASSERTE(hwnd != NULL);
|
||||
_ASSERTE(m_hwnd == NULL);
|
||||
m_hwnd = hwnd;
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
||||
m_pfnOldSplitterWndProc = SubclassWindow(hwnd, SplitterWndProc);
|
||||
ResetSplitterPos();
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
}
|
||||
|
||||
void CSplitter::Detach(void)
|
||||
{
|
||||
if (m_pfnOldSplitterWndProc)
|
||||
{
|
||||
SubclassWindow(m_hwnd, m_pfnOldSplitterWndProc);
|
||||
SetWindowLongPtr(m_hwnd, GWLP_USERDATA, NULL);
|
||||
ClearSplitterPos();
|
||||
ClearPanels();
|
||||
InvalidateRect(m_hwnd, NULL, TRUE);
|
||||
m_pfnOldSplitterWndProc = NULL;
|
||||
m_hwnd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CSplitter::ClearSplitterPos(void)
|
||||
{
|
||||
m_nIdealPos = m_nSplitterPos = m_nSplitterSize = 0;
|
||||
}
|
||||
|
||||
void CSplitter::ClearPanels(void)
|
||||
{
|
||||
m_arrPanels[0] = NULL;
|
||||
m_arrPanels[1] = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return splitter size value.
|
||||
*/
|
||||
int CSplitter::CalcSplitterSize(void) const
|
||||
{
|
||||
_ASSERTE(m_hwnd != NULL);
|
||||
RECT rect;
|
||||
GetClientRect(m_hwnd, &rect);
|
||||
int nSplitterSize, nEdgeType, nFrameType;
|
||||
if (m_eDirection == SD_VERTICAL)
|
||||
{
|
||||
nSplitterSize = rect.bottom;
|
||||
nEdgeType = SM_CYEDGE;
|
||||
nFrameType = SM_CYFRAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
nSplitterSize = rect.right;
|
||||
nEdgeType = SM_CXEDGE;
|
||||
nFrameType = SM_CXFRAME;
|
||||
}
|
||||
int nEdgeSize = GetSystemMetrics(nEdgeType) * 2;
|
||||
int nBarSize = GetSystemMetrics(nFrameType);
|
||||
nSplitterSize -= nBarSize;
|
||||
nSplitterSize -= nEdgeSize;
|
||||
if (nSplitterSize < 0)
|
||||
nSplitterSize = 0;
|
||||
return nSplitterSize;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue