You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1895 lines
54 KiB
C++
1895 lines
54 KiB
C++
// XTPDockingPaneContext.cpp : implementation of the CXTPDockingPaneContext class.
|
|
//
|
|
// This file is a part of the XTREME DOCKINGPANE MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "Resource.h"
|
|
|
|
#include "Common/XTPColorManager.h"
|
|
#include "Common/XTPDrawHelpers.h"
|
|
#include "Common/XTPResourceManager.h"
|
|
#include "Common/XTPSystemHelpers.h"
|
|
#include "Common/XTPImageManager.h"
|
|
|
|
#include "TabManager/XTPTabManager.h"
|
|
#include "TabManager/XTPTabPaintManager.h"
|
|
|
|
#include "XTPDockingPaneDefines.h"
|
|
#include "XTPDockingPaneBase.h"
|
|
#include "XTPDockingPaneBaseContainer.h"
|
|
#include "XTPDockingPaneContext.h"
|
|
#include "XTPDockingPane.h"
|
|
#include "XTPDockingPaneManager.h"
|
|
#include "XTPDockingPaneTabbedContainer.h"
|
|
#include "XTPDockingPaneSplitterContainer.h"
|
|
#include "XTPDockingPaneMiniWnd.h"
|
|
#include "XTPDockingPaneSidePanel.h"
|
|
#include "XTPDockingPanePaintManager.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
|
|
void AFX_CDECL CXTPDockingPaneContext::AdjustRectangle(CRect& rect, CPoint pt)
|
|
{
|
|
int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left - 6) :
|
|
(pt.x > rect.right) ? (pt.x - rect.right + 6) : 0;
|
|
int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top - 6) :
|
|
(pt.y > rect.bottom) ? (pt.y - rect.bottom + 6) : 0;
|
|
rect.OffsetRect(nXOffset, nYOffset);
|
|
}
|
|
|
|
void AFX_CDECL CXTPDockingPaneContext::AdjustCursor(CPoint& pt)
|
|
{
|
|
CRect rc = XTPMultiMonitor()->GetWorkArea(pt);
|
|
if (pt.x < rc.left) pt.x = rc.left;
|
|
if (pt.x > rc.right) pt.x = rc.right;
|
|
if (pt.y < rc.top) pt.y = rc.top;
|
|
if (pt.y > rc.bottom) pt.y = rc.bottom;
|
|
}
|
|
|
|
typedef BOOL (WINAPI *PFNSETLAYEREDWINDOWATTRIBUTES) (HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
|
|
|
|
#ifndef LWA_ALPHA
|
|
#define LWA_ALPHA 0x00000002
|
|
#endif
|
|
|
|
#ifndef WS_EX_LAYERED
|
|
#define WS_EX_LAYERED 0x00080000
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPDockingPaneContextAlphaWnd
|
|
|
|
CXTPDockingPaneContextAlphaWnd::CXTPDockingPaneContextAlphaWnd()
|
|
{
|
|
}
|
|
|
|
CXTPDockingPaneContextAlphaWnd::~CXTPDockingPaneContextAlphaWnd()
|
|
{
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPDockingPaneContextAlphaWnd, CWnd)
|
|
//{{AFX_MSG_MAP(CXTPDockingPaneContextAlphaWnd)
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_PAINT()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPDockingPaneContextAlphaWnd message handlers
|
|
|
|
BOOL CXTPDockingPaneContextAlphaWnd::OnEraseBkgnd(CDC* /*pDC*/)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPDockingPaneContextAlphaWnd::OnPaint()
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
CRect rc;
|
|
GetClientRect(&rc);
|
|
|
|
dc.FillSolidRect(rc, GetSysColor(COLOR_HIGHLIGHT));
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPDockingPaneContextStickerWnd
|
|
|
|
CXTPDockingPaneContextStickerWnd::CXTPDockingPaneContextStickerWnd(CXTPDockingPaneContext* pContext)
|
|
: m_pContext(pContext)
|
|
{
|
|
m_typeSticker = m_selectedSticker = xtpPaneStickerNone;
|
|
}
|
|
|
|
CXTPDockingPaneContextStickerWnd::~CXTPDockingPaneContextStickerWnd()
|
|
{
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPDockingPaneContextStickerWnd, CWnd)
|
|
//{{AFX_MSG_MAP(CXTPDockingPaneContextStickerWnd)
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_PAINT()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPDockingPaneContextAlphaWnd message handlers
|
|
|
|
BOOL CXTPDockingPaneContextStickerWnd::OnEraseBkgnd(CDC* /*pDC*/)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
struct CXTPDockingPaneContextStickerWnd::SPRITEINFO
|
|
{
|
|
SPRITEINFO(int x, int y, int left, int top, int cx, int cy)
|
|
{
|
|
ptDest = CPoint(x, y);
|
|
rcSrc.SetRect(left, top, left + cx, top + cy);
|
|
}
|
|
CPoint ptDest;
|
|
CRect rcSrc;
|
|
};
|
|
|
|
#define SPRITE_STICKER_TOP 0
|
|
#define SPRITE_STICKER_LEFT 1
|
|
#define SPRITE_STICKER_BOTTOM 2
|
|
#define SPRITE_STICKER_RIGHT 3
|
|
#define SPRITE_STICKER_TOP_SELECTED 4
|
|
#define SPRITE_STICKER_LEFT_SELECTED 5
|
|
#define SPRITE_STICKER_BOTTOM_SELECTED 6
|
|
#define SPRITE_STICKER_RIGHT_SELECTED 7
|
|
|
|
#define SPRITE_STICKER_CENTER 8
|
|
#define SPRITE_STICKER_CENTER_SELECTED 9
|
|
#define SPRITE_STICKER_CLIENT 10
|
|
|
|
static CXTPDockingPaneContextStickerWnd::SPRITEINFO arrSpritesStyckerWidbey[] =
|
|
{
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(25, 0, 0, 0, 43, 30),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 25, 30, 33, 30, 43),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(25, 63, 43, 0, 43, 30),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(63, 25, 0, 33, 30, 43),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(25, 0, 0, 76, 43, 30),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 25, 90, 33, 30, 43),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(25, 63, 43, 76, 43, 30),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(63, 25, 60, 33, 30, 43),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 30, 86, 0, 33, 33),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 30, 86, 76, 33, 33),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(25, 25, 0, 0, 43, 43),
|
|
};
|
|
|
|
static CXTPDockingPaneContextStickerWnd::SPRITEINFO arrSpritesStyckerVisualStudio2005[] =
|
|
{
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 0, 61, 29, 29, 30),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 30, 90, 30, 30, 29),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 59, 91, 0, 29, 30),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(60, 30, 62, 0, 30, 29),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 0, 61, 29 + 61, 29, 30),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 30, 90, 30 + 61, 30, 29),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 59, 91, 0 + 61, 29, 30),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(60, 30, 62, 0 + 61, 30, 29),
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(30, 30, 120, 82, 28, 29),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(24, 24, 120, 41, 41, 41),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(24, 24, 120, 0, 41, 41),
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 29, 29, 32),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 29, 32, 32, 29),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 32, 0, 29, 32),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 0, 32, 29),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 29 + 61, 29, 32),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 29, 32 + 61, 32, 29),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 32, 0 + 61, 29, 32),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 0 + 61, 32, 29),
|
|
|
|
};
|
|
|
|
static CXTPDockingPaneContextStickerWnd::SPRITEINFO arrSpritesStyckerVisualStudio2008[] =
|
|
{
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 0, 142, 35, 35, 35),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 35, 142 + 35, 35, 35, 35),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 70, 142 + 35, 0, 35, 35),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(72, 35, 142, 0, 35, 35),
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 0, 212, 35, 35, 35),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 35, 212 + 35, 35, 35, 35),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 70, 212 + 35, 0, 35, 35),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(72, 35, 212, 0, 35, 35),
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(37, 38, 359, 0, 32, 31),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(37, 38, 359, 31, 32, 31),
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(15, 15, 282, 0, 77, 75), // Client
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 35, 35, 36),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 35, 36, 36, 35),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 36, 0, 35, 36),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 0, 36, 35),
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0 + 71, 35, 35, 36),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 35 + 71, 36, 36, 35),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 36 + 71, 0, 35, 36),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0 + 71, 0, 36, 35),
|
|
|
|
};
|
|
|
|
|
|
static CXTPDockingPaneContextStickerWnd::SPRITEINFO arrSpritesStyckerVisualStudio2010[] =
|
|
{
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 0, 80, 40, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 36, 80 + 40, 40, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 72, 80 + 40, 0, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(72, 36, 80, 0, 40, 40),
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 0, 80, 40 + 80, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 36, 80 + 40, 40 + 80, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(36, 72, 80 + 40, 0 + 80, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(72, 36, 80, 0 + 80, 40, 40),
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(40, 40, 160, 120, 32, 32),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(40, 40, 192, 120, 32, 32),
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 160, 0, 112, 112), // Client
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 40, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 40, 40, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 40, 0, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 0, 40, 40),
|
|
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 40 + 80, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 40, 40 + 80, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 40, 0 + 80, 40, 40),
|
|
CXTPDockingPaneContextStickerWnd::SPRITEINFO(0, 0, 0, 0 + 80, 40, 40),
|
|
|
|
};
|
|
|
|
|
|
void CXTPDockingPaneContextStickerWnd::DrawTransparent(CDC* pDC , const CPoint& ptDest, const CSize& sz, CBitmap* pBitmap)
|
|
{
|
|
CImageList il;
|
|
il.Create(sz.cx, sz.cy, ILC_COLOR24 | ILC_MASK, 0, 1);
|
|
il.Add(pBitmap, RGB(0, 0xFF, 0));
|
|
|
|
il.Draw(pDC, 0, ptDest, ILD_NORMAL);
|
|
}
|
|
|
|
void CXTPDockingPaneContextStickerWnd::DrawSprite(CDC* pDC, UINT nID, SPRITEINFO* pSpriteInfo, BOOL bClientBitmap)
|
|
{
|
|
CBitmap bmp;
|
|
|
|
{
|
|
CXTPResourceManager::CManageState state;
|
|
bmp.Attach(CXTPImageManagerIcon::LoadBitmapFromResource(MAKEINTRESOURCE(nID), NULL));
|
|
}
|
|
|
|
CSize sz(pSpriteInfo->rcSrc.Width(), pSpriteInfo->rcSrc.Height());
|
|
|
|
CBitmap bmpSprite;
|
|
bmpSprite.CreateCompatibleBitmap(pDC, sz.cx, sz.cy);
|
|
|
|
if (bmpSprite.GetSafeHandle())
|
|
{
|
|
CXTPCompatibleDC dcSprite(pDC, &bmpSprite);
|
|
CXTPCompatibleDC dc(pDC, &bmp);
|
|
dcSprite.BitBlt(0, 0, sz.cx, sz.cy, &dc, pSpriteInfo->rcSrc.left, pSpriteInfo->rcSrc.top, SRCCOPY);
|
|
}
|
|
|
|
CPoint ptDest = bClientBitmap ? pSpriteInfo->ptDest : CPoint(0, 0);
|
|
|
|
DrawTransparent(pDC, ptDest, sz, &bmpSprite);
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneContextStickerWnd::OnDraw(CDC* pDC)
|
|
{
|
|
BOOL bClient = (m_typeSticker & xtpPaneStickerClient) == xtpPaneStickerClient;
|
|
XTPDockingContextStickerStyle style = m_pContext->GetStickerStyle();
|
|
|
|
if (style == xtpPaneStickerStyleVisualStudio2005Beta)
|
|
{
|
|
XTPCurrentSystemTheme theme = XTPColorManager()->GetCurrentSystemTheme();
|
|
|
|
UINT nIDBitmap = theme == xtpSystemThemeOlive ? XTP_IDB_DOCKINGPANE_STICKERS_OLIVE :
|
|
theme == xtpSystemThemeSilver ? XTP_IDB_DOCKINGPANE_STICKERS_SILVER : XTP_IDB_DOCKINGPANE_STICKERS_BLUE;
|
|
|
|
SPRITEINFO* sprites = arrSpritesStyckerWidbey;
|
|
|
|
if (bClient)
|
|
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKER_CLIENT, &sprites[SPRITE_STICKER_CLIENT]);
|
|
if (m_typeSticker & xtpPaneStickerTop)
|
|
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerTop ? SPRITE_STICKER_TOP_SELECTED : SPRITE_STICKER_TOP], bClient);
|
|
if (m_typeSticker & xtpPaneStickerLeft)
|
|
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerLeft ? SPRITE_STICKER_LEFT_SELECTED : SPRITE_STICKER_LEFT], bClient);
|
|
if (m_typeSticker & xtpPaneStickerBottom)
|
|
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerBottom ? SPRITE_STICKER_BOTTOM_SELECTED : SPRITE_STICKER_BOTTOM], bClient);
|
|
if (m_typeSticker & xtpPaneStickerRight)
|
|
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerRight ? SPRITE_STICKER_RIGHT_SELECTED : SPRITE_STICKER_RIGHT], bClient);
|
|
if (m_typeSticker & xtpPaneStickerCenter)
|
|
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerCenter ? SPRITE_STICKER_CENTER_SELECTED : SPRITE_STICKER_CENTER]);
|
|
}
|
|
else if (style == xtpPaneStickerStyleVisualStudio2008 || style == xtpPaneStickerStyleVisualStudio2010)
|
|
{
|
|
UINT nIDBitmap = style == xtpPaneStickerStyleVisualStudio2008 ? XTP_IDB_DOCKINGPANE_STICKERS_2008 : XTP_IDB_DOCKINGPANE_STICKERS_2010;
|
|
SPRITEINFO* sprites = style == xtpPaneStickerStyleVisualStudio2008 ? arrSpritesStyckerVisualStudio2008 : arrSpritesStyckerVisualStudio2010;
|
|
int nClientSprite = bClient ? 0 : 11;
|
|
|
|
if (bClient)
|
|
{
|
|
DrawSprite(pDC, nIDBitmap, &sprites[SPRITE_STICKER_CLIENT]);
|
|
|
|
if (m_typeSticker & xtpPaneStickerCenter)
|
|
DrawSprite(pDC, nIDBitmap, &sprites[m_selectedSticker == xtpPaneStickerCenter ? SPRITE_STICKER_CENTER_SELECTED : SPRITE_STICKER_CENTER]);
|
|
}
|
|
|
|
if (m_typeSticker & xtpPaneStickerTop)
|
|
DrawSprite(pDC, nIDBitmap, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerTop ? SPRITE_STICKER_TOP_SELECTED : SPRITE_STICKER_TOP)], bClient);
|
|
if (m_typeSticker & xtpPaneStickerLeft)
|
|
DrawSprite(pDC, nIDBitmap, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerLeft ? SPRITE_STICKER_LEFT_SELECTED : SPRITE_STICKER_LEFT)], bClient);
|
|
if (m_typeSticker & xtpPaneStickerBottom)
|
|
DrawSprite(pDC, nIDBitmap, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerBottom ? SPRITE_STICKER_BOTTOM_SELECTED : SPRITE_STICKER_BOTTOM)], bClient);
|
|
if (m_typeSticker & xtpPaneStickerRight)
|
|
DrawSprite(pDC, nIDBitmap, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerRight ? SPRITE_STICKER_RIGHT_SELECTED : SPRITE_STICKER_RIGHT)], bClient);
|
|
|
|
}
|
|
else
|
|
{
|
|
SPRITEINFO* sprites = arrSpritesStyckerVisualStudio2005;
|
|
int nClientSprite = bClient ? 0 : 11;
|
|
|
|
if (bClient)
|
|
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[m_selectedSticker == xtpPaneStickerCenter ? SPRITE_STICKER_CENTER_SELECTED : SPRITE_STICKER_CLIENT]);
|
|
if (m_typeSticker & xtpPaneStickerTop)
|
|
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerTop ? SPRITE_STICKER_TOP_SELECTED : SPRITE_STICKER_TOP)], bClient);
|
|
if (m_typeSticker & xtpPaneStickerLeft)
|
|
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerLeft ? SPRITE_STICKER_LEFT_SELECTED : SPRITE_STICKER_LEFT)], bClient);
|
|
if (m_typeSticker & xtpPaneStickerBottom)
|
|
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerBottom ? SPRITE_STICKER_BOTTOM_SELECTED : SPRITE_STICKER_BOTTOM)], bClient);
|
|
if (m_typeSticker & xtpPaneStickerRight)
|
|
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[nClientSprite + (m_selectedSticker == xtpPaneStickerRight ? SPRITE_STICKER_RIGHT_SELECTED : SPRITE_STICKER_RIGHT)], bClient);
|
|
if (m_typeSticker & xtpPaneStickerCenter)
|
|
DrawSprite(pDC, XTP_IDB_DOCKINGPANE_STICKERS_2005, &sprites[SPRITE_STICKER_CENTER]);
|
|
}
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneContextStickerWnd::OnPaint()
|
|
{
|
|
CPaintDC dcPaint(this); // device context for painting
|
|
CXTPBufferDC dc(dcPaint, CXTPClientRect(this));
|
|
|
|
OnDraw(&dc);
|
|
}
|
|
|
|
XTPDockingPaneStickerType CXTPDockingPaneContextStickerWnd::HitTest(CPoint pt)
|
|
{
|
|
CXTPClientRect rc(this);
|
|
ScreenToClient(&pt);
|
|
|
|
if (!rc.PtInRect(pt))
|
|
return xtpPaneStickerNone;
|
|
|
|
CClientDC dcClient(this);
|
|
|
|
CBitmap bmp;
|
|
bmp.CreateCompatibleBitmap(&dcClient, rc.Width(), rc.Height());
|
|
|
|
CXTPCompatibleDC dc(&dcClient, &bmp);
|
|
dc.FillSolidRect(rc, 0);
|
|
|
|
XTPDockingContextStickerStyle style = m_pContext->GetStickerStyle();
|
|
|
|
UINT nIDBitmap = style == xtpPaneStickerStyleVisualStudio2005 ? XTP_IDB_DOCKINGPANE_STICKERS_2005 :
|
|
style == xtpPaneStickerStyleVisualStudio2008 ? XTP_IDB_DOCKINGPANE_STICKERS_2008 :
|
|
style == xtpPaneStickerStyleVisualStudio2010 ? XTP_IDB_DOCKINGPANE_STICKERS_2010 : XTP_IDB_DOCKINGPANE_STICKERS_BLUE;
|
|
|
|
UINT nIDBitmapClient = style == xtpPaneStickerStyleVisualStudio2005Beta ? XTP_IDB_DOCKINGPANE_STICKER_CLIENT : nIDBitmap;
|
|
|
|
BOOL bClient = (m_typeSticker & xtpPaneStickerClient) == xtpPaneStickerClient;
|
|
|
|
SPRITEINFO* sprites = style == xtpPaneStickerStyleVisualStudio2005Beta ? arrSpritesStyckerWidbey :
|
|
style == xtpPaneStickerStyleVisualStudio2008 ? arrSpritesStyckerVisualStudio2008 :
|
|
style == xtpPaneStickerStyleVisualStudio2010 ? arrSpritesStyckerVisualStudio2010 : arrSpritesStyckerVisualStudio2005;
|
|
|
|
if (m_typeSticker & xtpPaneStickerTop)
|
|
{
|
|
DrawSprite(&dc, nIDBitmap, &sprites[SPRITE_STICKER_TOP], bClient);
|
|
if (dc.GetPixel(pt) != 0)
|
|
return xtpPaneStickerTop;
|
|
}
|
|
if (m_typeSticker & xtpPaneStickerLeft)
|
|
{
|
|
DrawSprite(&dc, nIDBitmap, &sprites[SPRITE_STICKER_LEFT], bClient);
|
|
if (dc.GetPixel(pt) != 0)
|
|
return xtpPaneStickerLeft;
|
|
}
|
|
if (m_typeSticker & xtpPaneStickerBottom)
|
|
{
|
|
DrawSprite(&dc, nIDBitmap, &sprites[SPRITE_STICKER_BOTTOM], bClient);
|
|
if (dc.GetPixel(pt) != 0)
|
|
return xtpPaneStickerBottom;
|
|
}
|
|
if (m_typeSticker & xtpPaneStickerRight)
|
|
{
|
|
DrawSprite(&dc, nIDBitmap, &sprites[SPRITE_STICKER_RIGHT], bClient);
|
|
if (dc.GetPixel(pt) != 0)
|
|
return xtpPaneStickerRight;
|
|
}
|
|
if (m_typeSticker & xtpPaneStickerCenter)
|
|
{
|
|
DrawSprite(&dc, nIDBitmapClient, &sprites[SPRITE_STICKER_CLIENT]);
|
|
if (dc.GetPixel(pt) != 0)
|
|
return xtpPaneStickerCenter;
|
|
}
|
|
|
|
return xtpPaneStickerNone;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPDockingPaneContext
|
|
|
|
CXTPDockingPaneContext::CXTPDockingPaneContext()
|
|
{
|
|
m_bUseAlphaContext = FALSE;
|
|
m_bUseDockingStickers = FALSE;
|
|
m_bDragKeyboard = FALSE;
|
|
|
|
m_pStickerPane = NULL;
|
|
m_pLastStickerPane = NULL;
|
|
m_pManager = NULL;
|
|
m_pPane = NULL;
|
|
m_pContainer = NULL;
|
|
m_bAttachLast = FALSE;
|
|
m_bSideDock = FALSE;
|
|
m_bAttach = FALSE;
|
|
m_bFloatable = TRUE;
|
|
m_bDockable = TRUE;
|
|
m_bDitherLast = FALSE;
|
|
m_containDirection = (XTPDockingPaneDirection)-1;
|
|
m_pDC = NULL;
|
|
|
|
m_pfnSetLayeredWindowAttributes = NULL;
|
|
|
|
HMODULE hLib = GetModuleHandle(_T("USER32"));
|
|
if (hLib)
|
|
{
|
|
m_pfnSetLayeredWindowAttributes = (PVOID) ::GetProcAddress(hLib, "SetLayeredWindowAttributes");
|
|
}
|
|
|
|
m_bResetDC = FALSE;
|
|
}
|
|
|
|
CXTPDockingPaneContext::~CXTPDockingPaneContext()
|
|
{
|
|
|
|
}
|
|
|
|
void CXTPDockingPaneContext::Drag(CXTPDockingPaneBase* pPane, CPoint point)
|
|
{
|
|
CRect rcPane = pPane->GetPaneWindowRect();
|
|
|
|
CWnd* pSite = pPane->GetDockingSite();
|
|
if (pSite && (pPane->GetType() == xtpPaneTypeDockingPane || pPane->GetType() == xtpPaneTypeTabbedContainer)
|
|
&& !pSite->IsKindOf(RUNTIME_CLASS(CXTPDockingPaneMiniWnd)))
|
|
{
|
|
CXTPDockingPane* pActivePane = pPane->GetType() == xtpPaneTypeTabbedContainer ?
|
|
((CXTPDockingPaneTabbedContainer*)pPane)->GetSelected() : (CXTPDockingPane*)pPane;
|
|
|
|
if (pActivePane)
|
|
{
|
|
CXTPDockingPaneTabbedContainer* pHolder = (CXTPDockingPaneTabbedContainer*)m_pManager->_GetHolder(pActivePane, TRUE);
|
|
pSite = pHolder ? pHolder->GetDockingSite() : NULL;
|
|
|
|
if (pSite && pSite->IsKindOf(RUNTIME_CLASS(CXTPDockingPaneMiniWnd)))
|
|
{
|
|
CRect rcFloating = ((CXTPDockingPaneMiniWnd*)pSite)->GetPaneWindowRect();
|
|
|
|
rcPane.right = rcPane.left + rcFloating.Width();
|
|
rcPane.bottom = rcPane.top + rcFloating.Height();
|
|
}
|
|
else if (!pHolder)
|
|
{
|
|
rcPane.right = rcPane.left + pActivePane->m_szDocking.cx;
|
|
rcPane.bottom = rcPane.top + pActivePane->m_szDocking.cy;
|
|
}
|
|
}
|
|
}
|
|
|
|
Drag(pPane, point, rcPane);
|
|
}
|
|
|
|
void CXTPDockingPaneContext::Drag(CXTPDockingPaneBase* pPane, CPoint pt, CRect rect)
|
|
{
|
|
m_bDragKeyboard = (pt == CPoint(-1, -1));
|
|
|
|
if (m_bDragKeyboard)
|
|
{
|
|
pt.x = rect.CenterPoint().x;
|
|
pt.y = rect.top + 15;
|
|
SetCursorPos(pt.x, pt.y);
|
|
}
|
|
|
|
m_ptSticky = m_ptLast = pt;
|
|
|
|
AdjustRectangle(rect, pt);
|
|
|
|
m_pPane = pPane;
|
|
m_rectDragFrameScreen = m_rectDragFrame = rect;
|
|
m_pDC = 0;
|
|
m_pContainer = 0;
|
|
m_bAttach = m_bAttachLast = FALSE;
|
|
m_bFloatable = TRUE;
|
|
m_bDockable = TRUE;
|
|
m_bSideDock = FALSE;
|
|
|
|
m_bUseAlphaContext = m_pManager->IsAlphaDockingContext() && (m_pfnSetLayeredWindowAttributes != NULL);
|
|
m_bUseDockingStickers = m_pManager->IsShowDockingContextStickers() && m_bUseAlphaContext;
|
|
|
|
|
|
CXTPDockingPaneBaseList lst;
|
|
pPane->FindPane(xtpPaneTypeDockingPane, &lst);
|
|
POSITION pos = lst.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pListPane = (CXTPDockingPane*)lst.GetNext(pos);
|
|
|
|
if (m_pManager->NotifyAction(xtpPaneActionFloating, pListPane))
|
|
m_bFloatable = FALSE;
|
|
|
|
if (pListPane->GetOptions() & xtpPaneNoFloatable)
|
|
m_bFloatable = FALSE;
|
|
|
|
if (pListPane->GetOptions() & xtpPaneNoDockable)
|
|
m_bDockable = FALSE;
|
|
}
|
|
|
|
if (m_pManager->m_bShowSizeCursorWhileDragging)
|
|
{
|
|
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));
|
|
}
|
|
|
|
|
|
InitLoop();
|
|
|
|
Track();
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneContext::InitLoop()
|
|
{
|
|
m_rectLast.SetRectEmpty();
|
|
m_sizeLast.cx = m_sizeLast.cy = 0;
|
|
m_bDitherLast = FALSE;
|
|
m_rectStickerPane.SetRectEmpty();
|
|
m_pStickerPane = NULL;
|
|
m_pLastStickerPane = NULL;
|
|
m_bResetDC = FALSE;
|
|
|
|
if (!m_bUseAlphaContext)
|
|
{
|
|
// handle pending WM_PAINT messages
|
|
MSG msg;
|
|
while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
|
|
{
|
|
if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
|
|
return;
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
// lock window update while dragging
|
|
ASSERT(m_pDC == NULL);
|
|
CWnd* pWnd = CWnd::GetDesktopWindow();
|
|
if (pWnd->LockWindowUpdate())
|
|
m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
|
|
else
|
|
m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE);
|
|
ASSERT(m_pDC != NULL);
|
|
}
|
|
}
|
|
void CXTPDockingPaneContext::CancelLoop()
|
|
{
|
|
ReleaseCapture();
|
|
|
|
if (m_bUseAlphaContext)
|
|
{
|
|
m_wndContext.DestroyWindow();
|
|
m_wndAttachedTab.DestroyWindow();
|
|
|
|
DestroyDockingStickers();
|
|
|
|
POSITION pos = m_rgnStickers.GetStartPosition();
|
|
while (pos)
|
|
{
|
|
UINT nKey;
|
|
CRgn* pRgn;
|
|
m_rgnStickers.GetNextAssoc(pos, nKey, pRgn);
|
|
delete pRgn;
|
|
}
|
|
m_rgnStickers.RemoveAll();
|
|
|
|
}
|
|
else
|
|
{
|
|
DrawFocusRect(TRUE); // gets rid of focus rect
|
|
|
|
CWnd* pWnd = CWnd::GetDesktopWindow();
|
|
pWnd->UnlockWindowUpdate();
|
|
if (m_pDC != NULL)
|
|
{
|
|
pWnd->ReleaseDC(m_pDC);
|
|
m_pDC = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneContext::_CreateRectangleRgn(CRgn& rgnResult, CRect rc)
|
|
{
|
|
CRgn rgnOutside, rgnInside;
|
|
rgnOutside.CreateRectRgnIndirect(&rc);
|
|
CRect rect = rc;
|
|
rect.DeflateRect(4, 4);
|
|
rect.IntersectRect(rect, rc);
|
|
rgnInside.CreateRectRgnIndirect(rect);
|
|
rgnResult.CreateRectRgn(0, 0, 0, 0);
|
|
rgnResult.CombineRgn(&rgnOutside, &rgnInside, RGN_XOR);
|
|
}
|
|
|
|
void CXTPDockingPaneContext::_CreateRgn(CRgn& rgnResult, CRect rc, BOOL bTabbedRgn, BOOL bRemove)
|
|
{
|
|
if (bRemove)
|
|
{
|
|
rgnResult.CreateRectRgn(0, 0, 0, 0);
|
|
return;
|
|
}
|
|
|
|
if (bTabbedRgn)
|
|
{
|
|
CSize szTab(min(50, rc.Width() - 5), min(20, rc.Height() / 2));
|
|
CRect rcIntersect, rcTop(rc.left, rc.top, rc.right, rc.bottom - szTab.cy),
|
|
rcBottom(rc.left + 5, rc.bottom - szTab.cy - 4, rc.left + 5 + szTab.cx, rc.bottom);
|
|
|
|
CRgn rgnTop, rgnBottom, rgnIntersect;
|
|
|
|
rcIntersect.IntersectRect(rcTop, rcBottom);
|
|
rcIntersect.DeflateRect(4, 0);
|
|
|
|
_CreateRectangleRgn(rgnTop, rcTop);
|
|
_CreateRectangleRgn(rgnBottom, rcBottom);
|
|
_CreateRectangleRgn(rgnIntersect, rcIntersect);
|
|
|
|
rgnResult.CreateRectRgn(0, 0, 0, 0);
|
|
rgnResult.CombineRgn(&rgnBottom, &rgnTop, RGN_OR);
|
|
rgnResult.CombineRgn(&rgnResult, &rgnIntersect, RGN_XOR);
|
|
}
|
|
else
|
|
{
|
|
_CreateRectangleRgn(rgnResult, rc);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneContext::DrawFocusRect(BOOL bRemoveRect)
|
|
{
|
|
if (m_pManager->m_bShowContentsWhileDragging && m_pContainer == NULL &&
|
|
m_bFloatable && !m_bAttach && !m_rectDragFrame.IsRectEmpty())
|
|
{
|
|
CRect rect = m_rectDragFrame;
|
|
|
|
m_wndAttachedTab.DestroyWindow();
|
|
m_wndContext.DestroyWindow();
|
|
|
|
if (!m_bUseAlphaContext && !m_bResetDC)
|
|
{
|
|
ASSERT(m_pDC != NULL);
|
|
// determine new rect and size
|
|
|
|
rect.SetRectEmpty();
|
|
|
|
// first, determine the update region and select it
|
|
CRgn rgnNew, rgnLast, rgnUpdate;
|
|
|
|
_CreateRgn(rgnNew, rect, m_bAttach, TRUE);
|
|
_CreateRgn(rgnLast, m_rectLast, m_bAttachLast);
|
|
|
|
rgnUpdate.CreateRectRgn(0, 0, 0, 0);
|
|
rgnUpdate.CombineRgn(&rgnLast, &rgnNew, RGN_XOR);
|
|
|
|
// draw into the update/new region
|
|
m_pDC->SelectClipRgn(&rgnUpdate);
|
|
m_pDC->GetClipBox(&rect);
|
|
CBrush* pBrushOld = m_pDC->SelectObject(CDC::GetHalftoneBrush());
|
|
m_pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
|
|
// cleanup DC
|
|
|
|
if (pBrushOld != NULL)
|
|
m_pDC->SelectObject(pBrushOld);
|
|
|
|
m_pDC->SelectClipRgn(NULL);
|
|
|
|
CWnd* pWnd = CWnd::GetDesktopWindow();
|
|
pWnd->UnlockWindowUpdate();
|
|
if (m_pDC != NULL)
|
|
{
|
|
pWnd->ReleaseDC(m_pDC);
|
|
m_pDC = NULL;
|
|
}
|
|
m_bResetDC = TRUE;
|
|
}
|
|
|
|
if (m_pPane->GetType() == xtpPaneTypeSplitterContainer)
|
|
{
|
|
if (m_rectDragFrame != m_rectLast)
|
|
{
|
|
m_pPane->GetDockingSite()->MoveWindow(m_rectDragFrame);
|
|
}
|
|
}
|
|
else if (!bRemoveRect)
|
|
{
|
|
XTPDockingPaneAction actionNotify = xtpPaneActionFloated;
|
|
|
|
CXTPDockingPaneBaseList lst;
|
|
m_pPane->FindPane(xtpPaneTypeDockingPane, &lst);
|
|
|
|
if (m_rectDragFrame.top < 0)
|
|
m_rectDragFrame.OffsetRect(0, -m_rectDragFrame.top);
|
|
|
|
CXTPDockingPaneMiniWnd* pMiniWnd = m_pManager->FloatPane(m_pPane, m_rectDragFrame);
|
|
|
|
m_pManager->RecalcFrameLayout(m_pPane);
|
|
SAFE_CALLPTR(pMiniWnd, RecalcLayout());
|
|
|
|
m_pPane = pMiniWnd->GetTopPane();
|
|
|
|
POSITION pos = lst.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)lst.GetNext(pos);
|
|
m_pManager->NotifyAction(actionNotify, pPane);
|
|
}
|
|
|
|
XTPGetThread()->PumpMessage();
|
|
XTPGetThread()->OnIdle(0);
|
|
}
|
|
|
|
m_rectLast = rect;
|
|
m_bAttachLast = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
if (m_bResetDC)
|
|
{
|
|
ASSERT(m_pDC == NULL);
|
|
ASSERT(m_bUseAlphaContext == FALSE);
|
|
|
|
// handle pending WM_PAINT messages
|
|
MSG msg;
|
|
while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
|
|
{
|
|
if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
|
|
return;
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
// lock window update while dragging
|
|
CWnd* pWnd = CWnd::GetDesktopWindow();
|
|
if (pWnd->LockWindowUpdate())
|
|
m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
|
|
else
|
|
m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE);
|
|
ASSERT(m_pDC != NULL);
|
|
m_bResetDC = FALSE;
|
|
|
|
m_sizeLast.cx = m_sizeLast.cy = 0;
|
|
m_bDitherLast = FALSE;
|
|
m_rectLast.SetRectEmpty();
|
|
}
|
|
|
|
if (m_bUseAlphaContext)
|
|
{
|
|
ASSERT(bRemoveRect == FALSE);
|
|
|
|
CRect rect = (m_pContainer == 0) ? m_rectDragFrame : m_rectContainer;
|
|
|
|
m_rectLast = rect;
|
|
|
|
if (!m_bFloatable && m_pContainer == 0)
|
|
{
|
|
rect.SetRectEmpty();
|
|
}
|
|
|
|
if (m_bAttach != m_bAttachLast)
|
|
{
|
|
m_bAttachLast = m_bAttach;
|
|
if (m_bAttach)
|
|
CreateContextWindow(&m_wndAttachedTab);
|
|
else
|
|
m_wndAttachedTab.DestroyWindow();
|
|
}
|
|
|
|
if (m_bAttach)
|
|
{
|
|
CSize szTab(min(50, rect.Width() - 5), min(20, rect.Height() / 2));
|
|
CRect rcTab;
|
|
|
|
if (m_pManager->GetPaintManager()->GetTabPaintManager()->GetPosition() == xtpTabPositionTop
|
|
&& m_pContainer && m_pContainer->GetType() == xtpPaneTypeTabbedContainer)
|
|
{
|
|
if (((CXTPDockingPaneTabbedContainer*)m_pContainer)->IsTitleVisible())
|
|
{
|
|
rect.top += m_pManager->GetPaintManager()->GetCaptionHeight() + 3;
|
|
}
|
|
|
|
rect.top += szTab.cy;
|
|
rcTab = CRect(rect.left + 5, rect.top - szTab.cy, rect.left + 5 + szTab.cx, rect.top);
|
|
}
|
|
else
|
|
{
|
|
rect.bottom -= szTab.cy;
|
|
rcTab = CRect(rect.left + 5, rect.bottom, rect.left + 5 + szTab.cx, rect.bottom + szTab.cy);
|
|
}
|
|
|
|
m_wndAttachedTab.SetWindowPos(0, rcTab.left, rcTab.top, rcTab.Width(), rcTab.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
|
|
}
|
|
|
|
if (m_wndContext.GetSafeHwnd() == 0 || CXTPWindowRect(&m_wndContext).Size() != rect.Size())
|
|
{
|
|
m_wndContext.DestroyWindow();
|
|
CreateContextWindow(&m_wndContext);
|
|
}
|
|
|
|
m_wndContext.SetWindowPos(0, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
|
|
}
|
|
else
|
|
{
|
|
ASSERT(m_pDC != NULL);
|
|
// determine new rect and size
|
|
CRect rect = (m_pContainer == 0) ? m_rectDragFrame : m_rectContainer;
|
|
|
|
if (!m_bFloatable && m_pContainer == 0)
|
|
rect.SetRectEmpty();
|
|
|
|
// first, determine the update region and select it
|
|
CRgn rgnNew, rgnLast, rgnUpdate;
|
|
|
|
_CreateRgn(rgnNew, rect, m_bAttach, bRemoveRect);
|
|
_CreateRgn(rgnLast, m_rectLast, m_bAttachLast);
|
|
|
|
rgnUpdate.CreateRectRgn(0, 0, 0, 0);
|
|
rgnUpdate.CombineRgn(&rgnLast, &rgnNew, RGN_XOR);
|
|
|
|
m_rectLast = rect;
|
|
m_bAttachLast = m_bAttach;
|
|
|
|
// draw into the update/new region
|
|
m_pDC->SelectClipRgn(&rgnUpdate);
|
|
m_pDC->GetClipBox(&rect);
|
|
CBrush* pBrushOld = m_pDC->SelectObject(CDC::GetHalftoneBrush());
|
|
m_pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
|
|
// cleanup DC
|
|
|
|
if (pBrushOld != NULL)
|
|
m_pDC->SelectObject(pBrushOld);
|
|
|
|
m_pDC->SelectClipRgn(NULL);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPDockingPaneContext::CanSideDock(CXTPDockingPaneBase* pPane, CRect rcFrame)
|
|
{
|
|
CRect rc = pPane->GetPaneWindowRect();
|
|
rc.DeflateRect(m_pManager->GetSideDockingMargin());
|
|
|
|
int dSize = 10;
|
|
|
|
if (rc.Height() == 0 || rc.Width() == 0 || rcFrame.Height() == 0 || rcFrame.Width() == 0)
|
|
return FALSE;
|
|
|
|
if (!CRect().IntersectRect(rc, rcFrame))
|
|
return FALSE;
|
|
|
|
m_rectContainer.SetRectEmpty();
|
|
|
|
if (abs(rcFrame.top - rc.top) < dSize)
|
|
{
|
|
m_containDirection = xtpPaneDockTop;
|
|
m_rectContainer = CRect(rcFrame.left, rc.top, rcFrame.right, rc.top + rcFrame.Height());
|
|
|
|
dSize = abs(rcFrame.top - rc.top);
|
|
}
|
|
|
|
if (abs(rc.bottom - rcFrame.bottom) < dSize)
|
|
{
|
|
m_containDirection = xtpPaneDockBottom;
|
|
m_rectContainer = CRect(rcFrame.left, rc.bottom - rcFrame.Height(), rcFrame.right, rc.bottom);
|
|
|
|
dSize = abs(rc.bottom - rcFrame.bottom);
|
|
}
|
|
|
|
if (abs(rcFrame.left - rc.left) < dSize)
|
|
{
|
|
m_containDirection = xtpPaneDockLeft;
|
|
m_rectContainer = CRect(rc.left, rcFrame.top, rc.left + rcFrame.Width(), rcFrame.bottom);
|
|
|
|
dSize = abs(rcFrame.left - rc.left);
|
|
}
|
|
|
|
if (abs(rc.right - rcFrame.right) < dSize)
|
|
{
|
|
m_containDirection = xtpPaneDockRight;
|
|
m_rectContainer = CRect(rc.right - rcFrame.Width(), rcFrame.top, rc.right, rcFrame.bottom);
|
|
}
|
|
|
|
if (!m_rectContainer.IsRectEmpty())
|
|
{
|
|
if (!IsAllowDockingTo(pPane, m_containDirection))
|
|
return FALSE;
|
|
|
|
m_pContainer = pPane;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneContext::CanDock(CRect rc, CPoint pt, CXTPDockingPaneBase* pPane, BOOL bInside)
|
|
{
|
|
double dSize = 20.0;
|
|
|
|
double dRatio = 1.0;
|
|
|
|
if (bInside && !m_bFloatable)
|
|
{
|
|
if (rc.Width() > 1 && rc.Height() > 1) dRatio = (double)rc.Height() / (double)rc.Width();
|
|
dSize = 32000.0;
|
|
}
|
|
|
|
if (rc.Height() == 0 || rc.Width() == 0)
|
|
return FALSE;
|
|
|
|
if (bInside && !rc.PtInRect(pt))
|
|
return FALSE;
|
|
|
|
if (!bInside && !CRect(rc.left - 20, rc.top - 20, rc.right + 20, rc.bottom + 20).PtInRect(pt))
|
|
return FALSE;
|
|
|
|
int nInside = bInside ? 1 : -1;
|
|
BOOL bFound = FALSE;
|
|
|
|
|
|
if ((double)abs(pt.y - rc.top) < dSize && nInside * (pt.y - rc.top) >= 0)
|
|
{
|
|
m_containDirection = xtpPaneDockTop;
|
|
dSize = (double)abs(pt.y - rc.top);
|
|
bFound = TRUE;
|
|
}
|
|
|
|
if ((double)abs(rc.bottom - pt.y) < dSize && nInside * (rc.bottom - pt.y) >= 0)
|
|
{
|
|
m_containDirection = xtpPaneDockBottom;
|
|
dSize = (double)abs(rc.bottom - pt.y);
|
|
bFound = TRUE;
|
|
}
|
|
|
|
if ((double)abs(pt.x - rc.left) * dRatio < dSize && nInside * (pt.x - rc.left) >= 0)
|
|
{
|
|
m_containDirection = xtpPaneDockLeft;
|
|
dSize = (double)abs(pt.x - rc.left) * dRatio;
|
|
bFound = TRUE;
|
|
}
|
|
|
|
if ((double)abs(rc.right - pt.x) * dRatio < dSize && nInside * (rc.right- pt.x) >= 0)
|
|
{
|
|
m_containDirection = xtpPaneDockRight;
|
|
bFound = TRUE;
|
|
}
|
|
|
|
if (bFound)
|
|
{
|
|
if (!IsAllowDockingTo(pPane, m_containDirection))
|
|
return FALSE;
|
|
|
|
m_rectContainer = m_pManager->_CalculateResultDockingRect(m_pPane, m_containDirection, pPane);
|
|
m_pContainer = pPane;
|
|
}
|
|
return bFound;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneContext::IsAllowDockingTo(CXTPDockingPaneBase* pPane, XTPDockingPaneDirection direction)
|
|
{
|
|
CXTPDockingPaneBaseList lst;
|
|
m_pPane->FindPane(xtpPaneTypeDockingPane, &lst);
|
|
POSITION pos = lst.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* p = (CXTPDockingPane*)lst.GetNext(pos);
|
|
|
|
if (m_pManager->NotifyAction(xtpPaneActionDocking, p, pPane, direction))
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneContext::IsAllowAttachTo(CXTPDockingPaneBase* pPane)
|
|
{
|
|
|
|
CXTPDockingPaneBaseList lst;
|
|
m_pPane->FindPane(xtpPaneTypeDockingPane, &lst);
|
|
POSITION pos = lst.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* p = (CXTPDockingPane*)lst.GetNext(pos);
|
|
|
|
if (m_pManager->NotifyAction(xtpPaneActionAttaching, p, pPane))
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneContext::IsBehind(CXTPDockingPaneBase* pPaneBase, CXTPDockingPaneBase* pPaneTest)
|
|
{
|
|
CWnd* pFrameBase = pPaneBase->GetDockingSite();
|
|
if (!pFrameBase || !pFrameBase->IsKindOf(RUNTIME_CLASS(CXTPDockingPaneMiniWnd)))
|
|
return TRUE;
|
|
|
|
CWnd* pFrameTest = pPaneTest->GetDockingSite();
|
|
if (!pFrameTest || !pFrameTest->IsKindOf(RUNTIME_CLASS(CXTPDockingPaneMiniWnd)))
|
|
return FALSE;
|
|
|
|
HWND hWndNext = ::GetWindow(pFrameBase->GetSafeHwnd(), GW_HWNDNEXT);
|
|
|
|
while (hWndNext)
|
|
{
|
|
if (hWndNext == pFrameTest->GetSafeHwnd())
|
|
return FALSE;
|
|
|
|
hWndNext = ::GetWindow(hWndNext, GW_HWNDNEXT);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPDockingPaneContext::FindContainer(CPoint pt)
|
|
{
|
|
CXTPDockingPaneInfoList* pList = &m_pManager->GetPaneList();
|
|
|
|
CXTPDockingPaneBase* pFloatingPane = NULL;
|
|
|
|
POSITION pos = pList->GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pNextPane = pList->GetNext(pos);
|
|
|
|
CXTPDockingPaneBase* pPane = pNextPane->GetContainer();
|
|
if (pPane == NULL)
|
|
continue;
|
|
|
|
ASSERT(pPane->GetType() == xtpPaneTypeTabbedContainer);
|
|
|
|
if (pPane->GetContainer() == 0 || pPane->GetContainer()->GetType() != xtpPaneTypeSplitterContainer)
|
|
continue;
|
|
|
|
if (! (::GetWindowLong(((CXTPDockingPaneTabbedContainer*)pPane)->GetSafeHwnd(), GWL_STYLE) & WS_VISIBLE))
|
|
continue;
|
|
|
|
if (m_pPane->ContainPane(pPane))
|
|
continue;
|
|
|
|
CRect rcClient = pPane->GetPaneWindowRect();
|
|
|
|
if (rcClient.PtInRect(pt) && pNextPane->IsFloating())
|
|
{
|
|
if (pFloatingPane == NULL || IsBehind(pFloatingPane, pPane))
|
|
{
|
|
pFloatingPane = pPane;
|
|
}
|
|
}
|
|
}
|
|
|
|
pos = pList->GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pNextPane = pList->GetNext(pos);
|
|
if (pNextPane->GetOptions() & xtpPaneNoDockable)
|
|
continue;
|
|
|
|
CXTPDockingPaneBase* pPane = pNextPane->GetContainer();
|
|
if (pPane == NULL)
|
|
continue;
|
|
|
|
if (pFloatingPane != NULL && pFloatingPane != pPane)
|
|
continue;
|
|
|
|
ASSERT(pPane->GetType() == xtpPaneTypeTabbedContainer);
|
|
|
|
if (pPane->GetContainer() == 0 || (pPane->GetContainer()->GetType() != xtpPaneTypeSplitterContainer && pPane->GetContainer()->GetType() != xtpPaneTypeSidePanel))
|
|
continue;
|
|
|
|
if (! (::GetWindowLong(((CXTPDockingPaneTabbedContainer*)pPane)->GetSafeHwnd(), GWL_STYLE) & WS_VISIBLE))
|
|
continue;
|
|
|
|
CRect rcClient = m_rectContainer = pPane->GetPaneWindowRect();
|
|
|
|
if (m_pPane->ContainPane(pPane))
|
|
continue;
|
|
|
|
if (((CXTPDockingPaneTabbedContainer*)pPane)->CanAttach(rcClient, pt))
|
|
{
|
|
if (IsAllowAttachTo(pPane))
|
|
{
|
|
m_pContainer = pPane;
|
|
m_bAttach = TRUE;
|
|
m_pStickerPane = 0;
|
|
m_rectStickerPane.SetRectEmpty();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
rcClient = m_rectContainer;
|
|
}
|
|
}
|
|
if (pPane->GetContainer()->GetType() == xtpPaneTypeSidePanel)
|
|
continue;
|
|
|
|
if (m_bUseDockingStickers)
|
|
{
|
|
if (rcClient.PtInRect(pt))
|
|
{
|
|
if (m_pStickerPane == NULL || IsBehind(m_pStickerPane, pPane))
|
|
{
|
|
m_rectStickerPane = m_rectContainer;
|
|
m_pStickerPane = pPane;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (CanDock(rcClient, pt, pPane))
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
if (pFloatingPane && m_bUseDockingStickers && m_pStickerPane == NULL && m_rectStickerPane.IsRectEmpty())
|
|
{
|
|
CXTPDockingPaneBase* pPane = m_pManager->GetTopPane();
|
|
if (pPane->GetPaneWindowRect().PtInRect(pt))
|
|
{
|
|
m_rectStickerPane = pPane->GetPaneWindowRect();
|
|
}
|
|
}
|
|
|
|
if (pFloatingPane)
|
|
return;
|
|
|
|
if (m_pManager->IsSideDockingEnabled())
|
|
{
|
|
if (CanSideDock(m_pManager->GetClientPane(), m_rectDragFrame))
|
|
{
|
|
m_bSideDock = TRUE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (m_bUseDockingStickers)
|
|
{
|
|
if (m_pStickerPane)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (m_rectStickerPane.IsRectEmpty())
|
|
{
|
|
CXTPDockingPaneBase* pPane = m_pManager->GetClientPane();
|
|
if (pPane->GetPaneWindowRect().PtInRect(pt))
|
|
{
|
|
m_rectStickerPane = pPane->GetPaneWindowRect();
|
|
m_pStickerPane = pPane;
|
|
return;
|
|
}
|
|
|
|
pPane = m_pManager->GetTopPane();
|
|
if (pPane->GetPaneWindowRect().PtInRect(pt))
|
|
{
|
|
m_rectStickerPane = pPane->GetPaneWindowRect();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CXTPDockingPaneBase* pPane;
|
|
|
|
pPane = m_pManager->GetClientPane();
|
|
m_rectContainer = pPane->GetPaneWindowRect();
|
|
if (CanDock(pPane->GetPaneWindowRect(), pt, pPane))
|
|
return;
|
|
|
|
pPane = m_pManager->GetTopPane();
|
|
m_rectContainer = pPane->GetPaneWindowRect();
|
|
if (CanDock(pPane->GetPaneWindowRect(), pt, pPane, FALSE))
|
|
return;
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneContext::EnsureVisible(CRect& rectDragFrame)
|
|
{
|
|
CRect rcWork = XTPMultiMonitor()->GetWorkArea(rectDragFrame);
|
|
int nGap = 10;
|
|
|
|
if (rcWork.bottom - rectDragFrame.top < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(0, rcWork.bottom - rectDragFrame.top - nGap);
|
|
}
|
|
if (rectDragFrame.bottom - rcWork.top < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(0, rcWork.top - rectDragFrame.bottom + nGap);
|
|
}
|
|
if (rcWork.right - rectDragFrame.left < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(rcWork.right - rectDragFrame.left - nGap, 0);
|
|
}
|
|
if (rectDragFrame.right - rcWork.left < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(rcWork.left - rectDragFrame.right + nGap, 0);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneContext::UpdateStickyFrame(CRect& rectDragFrame, CWnd* pHost)
|
|
{
|
|
int nGap = m_pManager->m_nStickyGap;
|
|
CXTPWindowRect rcWork(pHost);
|
|
|
|
if (rectDragFrame.bottom < rcWork.top - nGap || rectDragFrame.top > rcWork.bottom + nGap)
|
|
return;
|
|
|
|
if (rectDragFrame.right < rcWork.left - nGap || rectDragFrame.left > rcWork.right + nGap)
|
|
return;
|
|
|
|
if (abs(rcWork.bottom - rectDragFrame.top) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(0, rcWork.bottom - rectDragFrame.top);
|
|
}
|
|
if (abs(rectDragFrame.bottom - rcWork.top) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(0, rcWork.top - rectDragFrame.bottom);
|
|
}
|
|
if (abs(rcWork.left - rectDragFrame.right) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(rcWork.left - rectDragFrame.right, 0);
|
|
}
|
|
if (abs(rectDragFrame.left - rcWork.right) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(rcWork.right - rectDragFrame.left, 0);
|
|
}
|
|
if (abs(rectDragFrame.left - rcWork.left) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(rcWork.left - rectDragFrame.left, 0);
|
|
}
|
|
if (abs(rectDragFrame.right - rcWork.right) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(rcWork.right - rectDragFrame.right, 0);
|
|
}
|
|
if (abs(rectDragFrame.bottom - rcWork.bottom) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(0, rcWork.bottom - rectDragFrame.bottom);
|
|
}
|
|
if (abs(rectDragFrame.top - rcWork.top) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(0, rcWork.top - rectDragFrame.top);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneContext::UpdateStickyFrame(CRect& rectDragFrame)
|
|
{
|
|
CRect rcWork = XTPMultiMonitor()->GetWorkArea(rectDragFrame);
|
|
int nGap = m_pManager->m_nStickyGap;
|
|
|
|
if (abs(rcWork.top - rectDragFrame.top) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(0, rcWork.top - rectDragFrame.top);
|
|
}
|
|
if (abs(rectDragFrame.bottom - rcWork.bottom) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(0, rcWork.bottom - rectDragFrame.bottom);
|
|
}
|
|
if (abs(rcWork.right - rectDragFrame.right) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(rcWork.right - rectDragFrame.right, 0);
|
|
}
|
|
if (abs(rectDragFrame.left - rcWork.left) < nGap)
|
|
{
|
|
rectDragFrame.OffsetRect(rcWork.left - rectDragFrame.left, 0);
|
|
}
|
|
|
|
if ((m_pManager->GetSite()->GetStyle() & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
|
|
UpdateStickyFrame(rectDragFrame, m_pManager->GetSite());
|
|
|
|
CXTPDockingPaneBaseList* pList = &m_pManager->GetPaneStack();
|
|
POSITION pos = pList->GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pNextPane = pList->GetNext(pos);
|
|
if (pNextPane->GetType() != xtpPaneTypeMiniWnd)
|
|
continue;
|
|
|
|
CXTPDockingPaneMiniWnd* pWnd = (CXTPDockingPaneMiniWnd*)pNextPane;
|
|
if (pWnd->GetSafeHwnd() && pWnd->IsWindowVisible() && m_pPane->GetDockingSite() != pWnd)
|
|
{
|
|
UpdateStickyFrame(rectDragFrame, pWnd);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneContext::UpdateSizingStickyFrame(UINT nSide, CRect& rectDragFrame, CWnd* pHost)
|
|
{
|
|
int nGap = m_pManager->m_nStickyGap;
|
|
CXTPWindowRect rcWork(pHost);
|
|
|
|
if (rectDragFrame.bottom < rcWork.top - nGap || rectDragFrame.top > rcWork.bottom + nGap)
|
|
return;
|
|
|
|
if (rectDragFrame.right < rcWork.left - nGap || rectDragFrame.left > rcWork.right + nGap)
|
|
return;
|
|
|
|
if (abs(rectDragFrame.top - rcWork.bottom) < nGap && (nSide == WMSZ_TOP || nSide == WMSZ_TOPLEFT || nSide == WMSZ_TOPRIGHT))
|
|
{
|
|
rectDragFrame.top = rcWork.bottom;
|
|
}
|
|
if (abs(rectDragFrame.bottom - rcWork.top) < nGap && (nSide == WMSZ_BOTTOM || nSide == WMSZ_BOTTOMLEFT || nSide == WMSZ_BOTTOMRIGHT))
|
|
{
|
|
rectDragFrame.bottom = rcWork.top;
|
|
}
|
|
if (abs(rectDragFrame.left - rcWork.left) < nGap && (nSide == WMSZ_LEFT || nSide == WMSZ_TOPLEFT || nSide == WMSZ_BOTTOMLEFT))
|
|
{
|
|
rectDragFrame.left = rcWork.left;
|
|
}
|
|
if (abs(rectDragFrame.left - rcWork.right) < nGap && (nSide == WMSZ_LEFT || nSide == WMSZ_TOPLEFT || nSide == WMSZ_BOTTOMLEFT))
|
|
{
|
|
rectDragFrame.left = rcWork.right;
|
|
}
|
|
if (abs(rectDragFrame.right - rcWork.left) < nGap && (nSide == WMSZ_RIGHT || nSide == WMSZ_TOPRIGHT|| nSide == WMSZ_BOTTOMRIGHT))
|
|
{
|
|
rectDragFrame.right = rcWork.left;
|
|
}
|
|
if (abs(rectDragFrame.right - rcWork.right) < nGap && (nSide == WMSZ_RIGHT || nSide == WMSZ_TOPRIGHT|| nSide == WMSZ_BOTTOMRIGHT))
|
|
{
|
|
rectDragFrame.right = rcWork.right;
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneContext::OnSizingFloatingFrame(CXTPDockingPaneMiniWnd* pMiniWnd, UINT nSide, LPRECT lpRect)
|
|
{
|
|
if (!m_pManager->IsStickyFloatingFrames())
|
|
return;
|
|
|
|
CRect rectDragFrame(lpRect);
|
|
|
|
if ((m_pManager->GetSite()->GetStyle() & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
|
|
UpdateSizingStickyFrame(nSide, rectDragFrame, m_pManager->GetSite());
|
|
|
|
CXTPDockingPaneBaseList* pList = &m_pManager->GetPaneStack();
|
|
POSITION pos = pList->GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pNextPane = pList->GetNext(pos);
|
|
if (pNextPane->GetType() != xtpPaneTypeMiniWnd)
|
|
continue;
|
|
|
|
CXTPDockingPaneMiniWnd* pWnd = (CXTPDockingPaneMiniWnd*)pNextPane;
|
|
if (pWnd->GetSafeHwnd() && pWnd->IsWindowVisible() && pMiniWnd != pWnd)
|
|
{
|
|
UpdateSizingStickyFrame(nSide, rectDragFrame, pWnd);
|
|
}
|
|
}
|
|
|
|
*lpRect = rectDragFrame;
|
|
}
|
|
|
|
void CXTPDockingPaneContext::Move(CPoint pt)
|
|
{
|
|
CPoint ptOffset = pt - m_ptLast;
|
|
|
|
m_rectDragFrameScreen.OffsetRect(ptOffset);
|
|
|
|
if (CRect().IntersectRect(m_rectDragFrameScreen, XTPMultiMonitor()->GetWorkArea(m_rectDragFrame)))
|
|
{
|
|
m_rectDragFrame = m_rectDragFrameScreen;
|
|
}
|
|
|
|
EnsureVisible(m_rectDragFrame);
|
|
|
|
if (!m_rectDragFrame.IsRectEmpty() && m_pManager->m_bStickyFloatingFrames)
|
|
{
|
|
UpdateStickyFrame(m_rectDragFrame);
|
|
}
|
|
|
|
|
|
m_pContainer = 0;
|
|
m_bAttach = FALSE;
|
|
m_rectStickerPane.SetRectEmpty();
|
|
m_pStickerPane = NULL;
|
|
m_bSideDock = FALSE;
|
|
|
|
if (GetKeyState(VK_CONTROL) >= 0 && m_bDockable)
|
|
{
|
|
FindContainer(pt);
|
|
}
|
|
|
|
m_ptLast = pt;
|
|
|
|
if (m_bUseDockingStickers)
|
|
{
|
|
UpdateDockingStickers();
|
|
|
|
BOOL bFound = FALSE;
|
|
POSITION pos = m_lstStickers.GetTailPosition();
|
|
while (pos)
|
|
{
|
|
|
|
CXTPDockingPaneContextStickerWnd* pSticker = m_lstStickers.GetPrev(pos);
|
|
XTPDockingPaneStickerType selectedSticker = xtpPaneStickerNone;
|
|
|
|
if (!bFound)
|
|
{
|
|
XTPDockingPaneStickerType ht = pSticker->HitTest(pt);
|
|
if (ht != xtpPaneStickerNone)
|
|
{
|
|
if ((pSticker->m_typeSticker & xtpPaneStickerClient) == xtpPaneStickerClient)
|
|
{
|
|
m_pContainer = m_pStickerPane;
|
|
m_rectContainer = m_rectStickerPane;
|
|
}
|
|
else
|
|
{
|
|
m_pContainer = m_pManager->GetTopPane();
|
|
m_rectContainer = m_pContainer->GetPaneWindowRect();
|
|
}
|
|
|
|
switch (ht)
|
|
{
|
|
case xtpPaneStickerTop:
|
|
m_rectContainer.bottom = m_rectContainer.CenterPoint().y;
|
|
m_containDirection = xtpPaneDockTop;
|
|
break;
|
|
case xtpPaneStickerBottom:
|
|
m_rectContainer.top = m_rectContainer.CenterPoint().y;
|
|
m_containDirection = xtpPaneDockBottom;
|
|
break;
|
|
case xtpPaneStickerLeft:
|
|
m_rectContainer.right = m_rectContainer.CenterPoint().x;
|
|
m_containDirection = xtpPaneDockLeft;
|
|
break;
|
|
case xtpPaneStickerRight:
|
|
m_rectContainer.left = m_rectContainer.CenterPoint().x;
|
|
m_containDirection = xtpPaneDockRight;
|
|
break;
|
|
case xtpPaneStickerCenter:
|
|
m_bAttach = TRUE;
|
|
break;
|
|
}
|
|
|
|
BOOL bAllow = TRUE;
|
|
|
|
if ((ht != xtpPaneStickerCenter) && !IsAllowDockingTo(m_pContainer, m_containDirection))
|
|
{
|
|
m_pContainer = NULL;
|
|
bAllow = FALSE;
|
|
}
|
|
|
|
if ((ht == xtpPaneStickerCenter) && !IsAllowAttachTo(m_pContainer))
|
|
{
|
|
m_pContainer = NULL;
|
|
m_bAttach = FALSE;
|
|
bAllow = FALSE;
|
|
}
|
|
|
|
if (bAllow)
|
|
{
|
|
if (ht != xtpPaneStickerCenter)
|
|
m_rectContainer = m_pManager->_CalculateResultDockingRect(m_pPane, m_containDirection, m_pContainer);
|
|
|
|
selectedSticker = ht;
|
|
}
|
|
|
|
bFound = TRUE;
|
|
}
|
|
}
|
|
if (pSticker->m_selectedSticker != selectedSticker)
|
|
{
|
|
pSticker->m_selectedSticker = selectedSticker;
|
|
pSticker->Invalidate(FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
DrawFocusRect();
|
|
}
|
|
|
|
void CXTPDockingPaneContext::Track()
|
|
{
|
|
// don't handle if capture already set
|
|
if (::GetCapture() != NULL)
|
|
return;
|
|
|
|
HWND hwndCapture = m_pManager->GetSite()->GetSafeHwnd();
|
|
ASSERT(hwndCapture);
|
|
if (!hwndCapture)
|
|
return;
|
|
// set capture to the window which received this message
|
|
::SetCapture(hwndCapture);
|
|
ASSERT(hwndCapture == ::GetCapture());
|
|
|
|
BOOL bAccept = FALSE;
|
|
// get messages until capture lost or cancelled/accepted
|
|
while (::GetCapture() == hwndCapture)
|
|
{
|
|
MSG msg;
|
|
|
|
// handle pending WM_PAINT messages
|
|
while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE | PM_NOYIELD))
|
|
{
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
if (!::GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
AfxPostQuitMessage((int)msg.wParam);
|
|
break;
|
|
}
|
|
|
|
if (msg.message == WM_LBUTTONUP)
|
|
{
|
|
bAccept = TRUE;
|
|
break;
|
|
}
|
|
else if (msg.message == WM_MOUSEMOVE)
|
|
{
|
|
CSize sz = m_ptSticky - CPoint(msg.pt);
|
|
if (abs(sz.cx) > 4 || abs(sz.cy) > 4)
|
|
{
|
|
Move(msg.pt);
|
|
m_ptSticky = CPoint(0, 0);
|
|
}
|
|
}
|
|
else if (msg.message == WM_KEYDOWN || msg.message == WM_KEYUP)
|
|
{
|
|
if (m_bDragKeyboard && msg.message == WM_KEYDOWN)
|
|
{
|
|
if (msg.wParam == VK_RETURN)
|
|
{
|
|
bAccept = TRUE;
|
|
break;
|
|
}
|
|
if (msg.wParam >= VK_LEFT && msg.wParam <= VK_DOWN)
|
|
{
|
|
CPoint pt(m_ptLast);
|
|
if (msg.wParam == VK_LEFT)
|
|
pt.x -= 10;
|
|
else if (msg.wParam == VK_RIGHT)
|
|
pt.x += 10;
|
|
else if (msg.wParam == VK_UP)
|
|
pt.y -= 10;
|
|
else if (msg.wParam == VK_DOWN)
|
|
pt.y += 10;
|
|
|
|
AdjustCursor(pt);
|
|
SetCursorPos(pt.x, pt.y);
|
|
Move(pt);
|
|
m_ptSticky = CPoint(0, 0);
|
|
}
|
|
}
|
|
if (msg.wParam == VK_CONTROL)
|
|
{
|
|
Move(m_ptLast);
|
|
m_ptSticky = CPoint(0, 0);
|
|
}
|
|
if (msg.wParam == VK_ESCAPE)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
CancelLoop();
|
|
|
|
if (bAccept && m_ptSticky == CPoint(0, 0))
|
|
{
|
|
XTPDockingPaneAction actionNotify = xtpPaneActionFloated;
|
|
|
|
CXTPDockingPaneBaseList lst;
|
|
m_pPane->FindPane(xtpPaneTypeDockingPane, &lst);
|
|
|
|
if (m_bAttach)
|
|
{
|
|
ASSERT(m_pContainer->GetType() == xtpPaneTypeTabbedContainer);
|
|
m_pManager->AttachPane(m_pPane, m_pContainer);
|
|
actionNotify = xtpPaneActionAttached;
|
|
}
|
|
else if (m_bSideDock && m_pContainer && m_pContainer == m_pManager->GetClientPane())
|
|
{
|
|
CRect rectSide(m_rectContainer);
|
|
rectSide.OffsetRect(-m_pContainer->GetPaneWindowRect().TopLeft());
|
|
|
|
if (m_pPane->GetContainer() && m_pPane->GetContainer()->GetType() == xtpPaneTypeSidePanel)
|
|
((CXTPDockingPaneSidePanel*)m_pPane->GetContainer())->MovePanel(m_containDirection, rectSide);
|
|
else
|
|
m_pManager->DockSidePane(m_pPane, m_containDirection, rectSide);
|
|
|
|
actionNotify = xtpPaneActionDocked;
|
|
}
|
|
else if (m_pContainer)
|
|
{
|
|
m_pManager->DockPane(m_pPane, m_pManager->GetRTLDirection(m_containDirection), m_pContainer);
|
|
m_pManager->EnsureVisible(m_pContainer);
|
|
actionNotify = xtpPaneActionDocked;
|
|
}
|
|
else if (m_bFloatable)
|
|
{
|
|
CRect rcWork = XTPMultiMonitor()->GetWorkArea(m_rectDragFrame);
|
|
|
|
if (m_rectDragFrame.top < rcWork.top)
|
|
m_rectDragFrame.OffsetRect(0, rcWork.top - m_rectDragFrame.top);
|
|
|
|
if (m_pPane->GetType() == xtpPaneTypeSplitterContainer)
|
|
m_pPane->GetDockingSite()->MoveWindow(m_rectDragFrame);
|
|
else
|
|
m_pManager->FloatPane(m_pPane, m_rectDragFrame);
|
|
}
|
|
else
|
|
{
|
|
bAccept = FALSE;
|
|
}
|
|
|
|
if (bAccept)
|
|
{
|
|
POSITION pos = lst.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)lst.GetNext(pos);
|
|
m_pManager->NotifyAction(actionNotify, pPane, m_pContainer, m_containDirection);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneContext::DestroyDockingStickers()
|
|
{
|
|
while (!m_lstStickers.IsEmpty())
|
|
{
|
|
CWnd* pWnd = m_lstStickers.RemoveHead();
|
|
pWnd->DestroyWindow();
|
|
delete pWnd;
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneContext::IncludeRgnPart(CRgn* pRgn, int x1, int y, int x2)
|
|
{
|
|
if (x1 < x2)
|
|
{
|
|
CRgn rgnExclude;
|
|
rgnExclude.CreateRectRgn(x1, y, x2, y + 1);
|
|
pRgn->CombineRgn(pRgn, &rgnExclude, RGN_OR);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneContext::RegionFromBitmap(CRgn* pRgn, CDC* pDC, CRect rc)
|
|
{
|
|
CSize sz = rc.Size();
|
|
|
|
pRgn->CreateRectRgn(0, 0, 0, 0);
|
|
|
|
for (int y = 0; y < sz.cy; y++)
|
|
{
|
|
int nStart = 0, x = 0;
|
|
BOOL bTransparent = TRUE;
|
|
|
|
while (x < sz.cx)
|
|
{
|
|
BOOL bTransparentPixel = pDC->GetPixel(x, y) == 0;
|
|
|
|
if (bTransparent && !bTransparentPixel)
|
|
{
|
|
nStart = x;
|
|
bTransparent = FALSE;
|
|
}
|
|
else if (!bTransparent && bTransparentPixel)
|
|
{
|
|
IncludeRgnPart(pRgn, nStart, y, x);
|
|
bTransparent = TRUE;
|
|
}
|
|
x++;
|
|
}
|
|
if (!bTransparent)
|
|
{
|
|
IncludeRgnPart(pRgn, nStart, y, x);
|
|
}
|
|
}
|
|
}
|
|
|
|
CXTPDockingPaneContextStickerWnd* CXTPDockingPaneContext::CreateNewSticker(CRect rc, XTPDockingPaneStickerType typeSticker)
|
|
{
|
|
if (typeSticker == xtpPaneStickerNone || typeSticker == xtpPaneStickerClient)
|
|
return NULL;
|
|
|
|
CXTPDockingPaneContextStickerWnd* pWnd = new CXTPDockingPaneContextStickerWnd(this);
|
|
m_lstStickers.AddTail(pWnd);
|
|
|
|
pWnd->CreateEx(WS_EX_TOOLWINDOW, AfxRegisterWndClass(NULL, AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
|
|
0, WS_POPUP, CRect(0, 0, 0, 0), m_pManager->GetSite(), 0);
|
|
|
|
pWnd->m_typeSticker = typeSticker;
|
|
|
|
|
|
CRgn* pRgn = NULL;
|
|
if (!m_rgnStickers.Lookup(typeSticker, pRgn))
|
|
{
|
|
pRgn = new CRgn;
|
|
m_rgnStickers.SetAt(typeSticker, pRgn);
|
|
}
|
|
ASSERT(pRgn != NULL);
|
|
if (!pRgn)
|
|
return NULL;
|
|
|
|
if (!pRgn->GetSafeHandle())
|
|
{
|
|
CClientDC dcClient(pWnd);
|
|
CBitmap bmp;
|
|
bmp.CreateCompatibleBitmap(&dcClient, rc.Width(), rc.Height());
|
|
|
|
if (bmp.GetSafeHandle())
|
|
{
|
|
CXTPCompatibleDC dc(&dcClient, &bmp);
|
|
dc.FillSolidRect(rc, RGB(0, 0, 0));
|
|
pWnd->OnDraw(&dc);
|
|
|
|
RegionFromBitmap(pRgn, &dc, rc);
|
|
}
|
|
}
|
|
|
|
HRGN hRgn = ::CreateRectRgn(0, 0, 0, 0);
|
|
::CombineRgn(hRgn, (HRGN)pRgn->GetSafeHandle(), NULL, RGN_COPY);
|
|
|
|
pWnd->SetWindowRgn(hRgn, FALSE);
|
|
pWnd->SetWindowPos(0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
|
|
|
|
return pWnd;
|
|
}
|
|
|
|
CSize CXTPDockingPaneContext::GetStickerSize(XTPDockingPaneStickerType type) const
|
|
{
|
|
int cx, cy, sz;
|
|
if (GetStickerStyle() == xtpPaneStickerStyleVisualStudio2005)
|
|
{
|
|
cx = 32;
|
|
cy = 29;
|
|
sz = 89;
|
|
}
|
|
else if (GetStickerStyle() == xtpPaneStickerStyleVisualStudio2008)
|
|
{
|
|
cx = 36;
|
|
cy = 35;
|
|
sz = 109;
|
|
}
|
|
else if (GetStickerStyle() == xtpPaneStickerStyleVisualStudio2010)
|
|
{
|
|
cx = 40;
|
|
cy = 40;
|
|
sz = 112;
|
|
}
|
|
else
|
|
{
|
|
cx = 30;
|
|
cy = 43;
|
|
sz = 93;
|
|
}
|
|
|
|
if (type == xtpPaneStickerTop) return CSize(cy, cx);
|
|
if (type == xtpPaneStickerLeft) return CSize(cx, cy);
|
|
if (type == xtpPaneStickerBottom) return CSize(cy, cx);
|
|
if (type == xtpPaneStickerRight) return CSize(cx, cy);
|
|
return CSize(sz, sz);
|
|
}
|
|
|
|
XTPDockingContextStickerStyle CXTPDockingPaneContext::GetStickerStyle() const
|
|
{
|
|
return m_pManager->GetDockingContextStickerStyle();
|
|
|
|
}
|
|
|
|
void CXTPDockingPaneContext::UpdateDockingStickers()
|
|
{
|
|
if (m_rectStickerPane.IsRectEmpty())
|
|
{
|
|
m_pLastStickerPane = NULL;
|
|
DestroyDockingStickers();
|
|
return;
|
|
}
|
|
|
|
CSize sz(GetStickerSize(xtpPaneStickerClient));
|
|
CRect rc(m_rectStickerPane.CenterPoint(), sz);
|
|
rc.OffsetRect(- sz.cx / 2, - sz.cy / 2);
|
|
|
|
if (m_pLastStickerPane != m_pStickerPane || m_lstStickers.IsEmpty())
|
|
{
|
|
DestroyDockingStickers();
|
|
|
|
if (m_pStickerPane)
|
|
{
|
|
UINT allowStickers = xtpPaneStickerNone;
|
|
if (IsAllowDockingTo(m_pStickerPane, xtpPaneDockLeft)) allowStickers = allowStickers + xtpPaneStickerLeft;
|
|
if (IsAllowDockingTo(m_pStickerPane, xtpPaneDockRight)) allowStickers = allowStickers + xtpPaneStickerRight;
|
|
if (IsAllowDockingTo(m_pStickerPane, xtpPaneDockBottom)) allowStickers = allowStickers + xtpPaneStickerBottom;
|
|
if (IsAllowDockingTo(m_pStickerPane, xtpPaneDockTop)) allowStickers = allowStickers + xtpPaneStickerTop;
|
|
|
|
CreateNewSticker(rc, m_pStickerPane == m_pManager->GetClientPane() || !IsAllowAttachTo(m_pStickerPane) ? XTPDockingPaneStickerType(xtpPaneStickerClient + allowStickers) : XTPDockingPaneStickerType(xtpPaneStickerClient + allowStickers + xtpPaneStickerCenter));
|
|
}
|
|
|
|
CXTPDockingPaneBase* pTopPane = m_pManager->GetTopPane();
|
|
CRect rcWindow = pTopPane->GetPaneWindowRect();
|
|
|
|
if (IsAllowDockingTo(pTopPane, xtpPaneDockTop))
|
|
CreateNewSticker(CRect(CPoint(rcWindow.CenterPoint().x - GetStickerSize(xtpPaneStickerTop).cx / 2, rcWindow.top + 16), GetStickerSize(xtpPaneStickerTop)), xtpPaneStickerTop);
|
|
if (IsAllowDockingTo(pTopPane, xtpPaneDockLeft))
|
|
CreateNewSticker(CRect(CPoint(rcWindow.left + 16, rcWindow.CenterPoint().y - GetStickerSize(xtpPaneStickerLeft).cy/ 2), GetStickerSize(xtpPaneStickerLeft)), xtpPaneStickerLeft);
|
|
if (IsAllowDockingTo(pTopPane, xtpPaneDockBottom))
|
|
CreateNewSticker(CRect(CPoint(rcWindow.CenterPoint().x - GetStickerSize(xtpPaneStickerBottom).cx / 2, rcWindow.bottom - 16 - GetStickerSize(xtpPaneStickerBottom).cy), GetStickerSize(xtpPaneStickerBottom)), xtpPaneStickerBottom);
|
|
if (IsAllowDockingTo(pTopPane, xtpPaneDockRight))
|
|
CreateNewSticker(CRect(CPoint(rcWindow.right - GetStickerSize(xtpPaneStickerRight).cx - 16, rcWindow.CenterPoint().y - GetStickerSize(xtpPaneStickerRight).cy/ 2), GetStickerSize(xtpPaneStickerRight)), xtpPaneStickerRight);
|
|
|
|
m_pLastStickerPane = m_pStickerPane;
|
|
}
|
|
|
|
ASSERT(m_lstStickers.GetCount() < 6);
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneContext::CreateContextWindow(CXTPDockingPaneContextAlphaWnd* pWnd)
|
|
{
|
|
ASSERT(m_bUseAlphaContext);
|
|
|
|
if (pWnd->GetSafeHwnd())
|
|
return;
|
|
|
|
pWnd->CreateEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, AfxRegisterWndClass(NULL, AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
|
|
0, WS_POPUP, CRect(0, 0, 0, 0), m_pManager->GetSite(), 0);
|
|
|
|
if (m_pfnSetLayeredWindowAttributes)
|
|
{
|
|
((PFNSETLAYEREDWINDOWATTRIBUTES)m_pfnSetLayeredWindowAttributes)
|
|
(pWnd->m_hWnd, 0, 100, LWA_ALPHA);
|
|
}
|
|
}
|