зеркало из https://github.com/mozilla/pjs.git
976 строки
27 KiB
C++
976 строки
27 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
// navfram.cpp : implementation of the CNSNavFrame class
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "rdfliner.h"
|
|
#include "navfram.h"
|
|
#include "feimage.h"
|
|
#include "cxicon.h"
|
|
#include "prefapi.h"
|
|
#include "xp_ncent.h"
|
|
#include "navbar.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CNSNavFrame
|
|
|
|
#ifndef _AFXDLL
|
|
#undef new
|
|
#endif
|
|
IMPLEMENT_DYNCREATE(CNSNavFrame, CFrameWnd)
|
|
#ifndef _AFXDLL
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
BEGIN_MESSAGE_MAP(CNSNavFrame, CFrameWnd)
|
|
//{{AFX_MSG_MAP(CNSNavFrame)
|
|
// NOTE - the ClassWizard will add and remove mapping macros here.
|
|
// DO NOT EDIT what you see in these blocks of generated code !
|
|
ON_WM_CREATE()
|
|
ON_WM_SIZE()
|
|
ON_WM_NCLBUTTONDOWN()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_LBUTTONUP()
|
|
ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
|
|
ON_WM_CLOSE()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
#define MFS_MOVEFRAME 0x00000800L // no sizing, just moving
|
|
#define MFS_SYNCACTIVE 0x00000100L // synchronize activation w/ parent
|
|
#define MFS_4THICKFRAME 0x00000200L // thick frame all around (no tiles)
|
|
#define MFS_THICKFRAME 0x00000400L // use instead of WS_THICKFRAME
|
|
#define MFS_MOVEFRAME 0x00000800L // no sizing, just moving
|
|
#define MFS_BLOCKSYSMENU 0x00001000L // block hit testing on system menu
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CNSNavFrame construction/destruction
|
|
|
|
CNSNavFrame::CNSNavFrame()
|
|
{
|
|
m_nsContent= NULL;
|
|
m_bDragging = FALSE;
|
|
m_DragWnd = NULL;
|
|
m_Node = NULL;
|
|
m_pButton = NULL;
|
|
}
|
|
|
|
CNSNavFrame::~CNSNavFrame()
|
|
{
|
|
if (m_dwOverDockStyle == DOCKSTYLE_DOCKEDLEFT)
|
|
{
|
|
PREF_SetIntPref(gPrefDockPercentage, m_DockSize);
|
|
}
|
|
else if (m_dwOverDockStyle == DOCKSTYLE_FLOATING)
|
|
{
|
|
PREF_SetRectPref(gPrefFloatRect, (int16)m_rectFloat.left, (int16)m_rectFloat.top, (int16)m_rectFloat.right, (int16)m_rectFloat.bottom);
|
|
}
|
|
}
|
|
|
|
void CNSNavFrame::OnClose()
|
|
{
|
|
if (m_dwOverDockStyle == DOCKSTYLE_FLOATING)
|
|
{
|
|
GetWindowRect(&m_rectFloat);
|
|
}
|
|
|
|
CFrameWnd::OnClose();
|
|
}
|
|
|
|
void CNSNavFrame::UpdateTitleBar(HT_View pView)
|
|
{
|
|
CString title("Navigation Center [");
|
|
title += HT_GetNodeName(HT_TopNode(pView));
|
|
title += "]";
|
|
|
|
SetWindowText(title);
|
|
}
|
|
|
|
int CNSNavFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
#ifdef XP_WIN32
|
|
SetClassLong(GetSafeHwnd(), GCL_HICON, (long)LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(2)));
|
|
#else
|
|
SetClassWord(GetSafeHwnd(), GCW_HICON, (WORD)LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(2)));
|
|
#endif
|
|
LONG style = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE);
|
|
::SetWindowLong(GetSafeHwnd(), GWL_STYLE, style | WS_CLIPCHILDREN);
|
|
#ifdef XP_WIN32
|
|
::SetClassLong(GetSafeHwnd(), GCL_HBRBACKGROUND, (COLOR_BTNFACE + 1));
|
|
#else
|
|
::SetClassWord(GetSafeHwnd(), GCW_HBRBACKGROUND, (COLOR_BTNFACE + 1));
|
|
#endif
|
|
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// void CNSNavFrame::CreateNewNavCenter()
|
|
// Create a New NavCenter and Show it.
|
|
//------------------------------------------------------------------------
|
|
void CNSNavFrame::CreateNewNavCenter(CNSGenFrame* pParentFrame, BOOL useViewType, HT_ViewType viewType)
|
|
{
|
|
// OBSOLETE: WILL GO AWAY SOON
|
|
|
|
// Read in our float rect pref.
|
|
int16 left,right,top, bottom;
|
|
PREF_GetRectPref(gPrefFloatRect,&left, &top, &right, &bottom);
|
|
|
|
// Create the window there.
|
|
m_rectFloat.SetRect(left, top, right, bottom);
|
|
m_rectDrag = m_rectFloat;
|
|
|
|
CString title = "Navigation Center";
|
|
Create( NULL, title, WS_OVERLAPPEDWINDOW, m_rectFloat, NULL);
|
|
|
|
// Hide initially.
|
|
ShowWindow(SW_HIDE);
|
|
|
|
// Determine the pixels we should consume if docked
|
|
int32 width;
|
|
PREF_GetIntPref(gPrefDockPercentage, &width);
|
|
m_DockSize = (int)width;
|
|
|
|
// Read in our dockstyle
|
|
m_dwOverDockStyle = DOCKSTYLE_DOCKEDLEFT;
|
|
|
|
// Find out if a view should be displayed
|
|
|
|
if (pParentFrame != NULL)
|
|
{
|
|
// create a docked window
|
|
DockFrame(pParentFrame, m_dwOverDockStyle);
|
|
}
|
|
else
|
|
{
|
|
// Create a floating window
|
|
m_dwOverDockStyle = DOCKSTYLE_FLOATING;
|
|
}
|
|
|
|
// Show the window.
|
|
ShowWindow(SW_SHOW);
|
|
|
|
theApp.m_pRDFCX->TrackRDFWindow(this);
|
|
|
|
if (useViewType)
|
|
HT_SetSelectedView(GetHTPane(), HT_GetViewType(GetHTPane(), viewType));
|
|
}
|
|
|
|
void CNSNavFrame::DeleteNavCenter()
|
|
{
|
|
CFrameWnd *pLayout = GetParentFrame();
|
|
|
|
ShowWindow(SW_HIDE);
|
|
SetParent(NULL);
|
|
|
|
// Tell ParentFrame that we are not docked anymore.
|
|
if (pLayout)
|
|
pLayout->RecalcLayout();
|
|
|
|
if (m_DragWnd)
|
|
m_DragWnd->DestroyWindow();
|
|
|
|
PostMessage(WM_CLOSE);
|
|
|
|
UnhookFromButton();
|
|
}
|
|
|
|
void CNSNavFrame::UnhookFromButton()
|
|
{
|
|
if (m_pButton)
|
|
{
|
|
m_pButton->SetDepressed(FALSE);
|
|
m_pButton->Invalidate();
|
|
CRDFToolbarHolder* pHolder = (CRDFToolbarHolder*)(m_pButton->GetParent()->GetParent()->GetParent());
|
|
pHolder->SetCurrentButton(NULL);
|
|
m_pButton = NULL;
|
|
}
|
|
}
|
|
|
|
BOOL CNSNavFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
|
|
{
|
|
m_nsContent = CRDFContentView::DisplayRDFTreeFromResource(this, 0, 0, 100, 100, m_Node, pContext);
|
|
CRDFOutliner* pOutliner = (CRDFOutliner*)(m_nsContent->GetOutlinerParent()->GetOutliner());
|
|
SetHTNode(HT_TopNode(pOutliner->GetHTView()));
|
|
|
|
// Read in our float rect pref.
|
|
int16 left,right,top, bottom;
|
|
PREF_GetRectPref(gPrefFloatRect,&left, &top, &right, &bottom);
|
|
|
|
// Create the window there.
|
|
m_rectFloat.SetRect(left, top, right, bottom);
|
|
m_rectDrag = m_rectFloat;
|
|
|
|
// Determine the pixels we should consume if docked
|
|
int32 width;
|
|
PREF_GetIntPref(gPrefDockPercentage, &width);
|
|
m_DockSize = (int)width;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CNSNavFrame::OnSize( UINT nType, int cx, int cy )
|
|
{
|
|
if(m_dwOverDockStyle == DOCKSTYLE_FLOATING)
|
|
{
|
|
// Make sure our float rect always matches our size when floating.
|
|
GetWindowRect(&m_rectFloat);
|
|
PREF_SetRectPref(gPrefFloatRect, (int16)m_rectFloat.left, (int16)m_rectFloat.top, (int16)m_rectFloat.right, (int16)m_rectFloat.bottom);
|
|
}
|
|
else if (m_dwOverDockStyle == DOCKSTYLE_DOCKEDLEFT)
|
|
{
|
|
// Recompute our docked percentage if the tree is visible
|
|
CRect rect;
|
|
GetClientRect(&rect);
|
|
CalcClientArea(&m_parentRect);
|
|
m_DockWidth = m_DockSize = rect.Width();
|
|
PREF_SetIntPref(gPrefDockPercentage, m_DockSize);
|
|
}
|
|
|
|
int top = 0;
|
|
CRect tempRect;
|
|
m_nsContent->SetWindowPos(NULL, 0, 0, cx, cy, 0);
|
|
}
|
|
|
|
BOOL CNSNavFrame::PreCreateWindow(CREATESTRUCT & cs)
|
|
{
|
|
|
|
cs.lpszClass = AfxRegisterWndClass( CS_DBLCLKS,
|
|
theApp.LoadStandardCursor(IDC_ARROW),
|
|
(HBRUSH)(COLOR_BTNFACE + 1));
|
|
return (CFrameWnd::PreCreateWindow(cs));
|
|
}
|
|
|
|
CNSNavFrame* CNSNavFrame::CreateFramedRDFViewFromResource(CWnd* pParent, int xPos, int yPos,
|
|
int width, int height, HT_Resource node)
|
|
{
|
|
CNSNavFrame* pNavFrame = new CNSNavFrame();
|
|
pNavFrame->SetHTNode(node);
|
|
pNavFrame->Create(NULL, HT_GetNodeName(node), WS_POPUP,
|
|
CRect(xPos, yPos, width, height),
|
|
pParent);
|
|
pNavFrame->ShowWindow(SW_HIDE);
|
|
|
|
HT_View view = HT_GetSelectedView(pNavFrame->GetHTPane());
|
|
|
|
CRDFOutliner* pOutliner = (CRDFOutliner*)(pNavFrame->GetContentView()->GetOutlinerParent()->GetOutliner());
|
|
|
|
// Display in the appropriate spot depending on our tree state (docked, standalone, or popup)
|
|
CString treeState = HT_GetTreeStateForButton(node);
|
|
if (treeState == "Popup" || treeState == "popup")
|
|
{
|
|
// Actually appear at the specified position and set the popup flag to be true.
|
|
pNavFrame->SetDockStyle(DOCKSTYLE_POPUP);
|
|
|
|
pNavFrame->SetWindowPos(&wndTopMost, xPos, yPos, width, height, 0);
|
|
pNavFrame->ShowWindow(SW_SHOW);
|
|
pOutliner->SetIsPopup(TRUE);
|
|
|
|
}
|
|
else if (treeState == "Docked" || treeState == "docked")
|
|
{
|
|
// We're supposed to come up docked to the window. Call DockFrame after setting
|
|
// the correct dock style
|
|
pNavFrame->SetDockStyle(DOCKSTYLE_DOCKEDLEFT);
|
|
|
|
// Use the toolbar button to get to the top-level frame.
|
|
CRDFToolbarButton* pButton = (CRDFToolbarButton*)HT_GetNodeFEData(node);
|
|
CFrameWnd* pBaseWnd = pButton->GetTopLevelFrame();
|
|
if(pBaseWnd && pBaseWnd->IsKindOf(RUNTIME_CLASS(CNSGenFrame)))
|
|
{
|
|
CNSGenFrame* pFrame = (CNSGenFrame *)pBaseWnd;
|
|
pNavFrame->DockFrame(pFrame, DOCKSTYLE_DOCKEDLEFT);
|
|
}
|
|
else pNavFrame->DeleteNavCenter(); // Somehow couldn't find the window. Should never happen.
|
|
}
|
|
/*else if (treeState == "Standalone" || treeState == "standalone")
|
|
{
|
|
pNavFrame->SetDockStyle(DOCKSTYLE_FLOATING);
|
|
pNavFrame->MoveWindow(pNavFrame->GetFloatRect());
|
|
pNavFrame->ForceFloat(TRUE);
|
|
}*/
|
|
|
|
pOutliner->SetFocus();
|
|
|
|
pNavFrame->ShowWindow(SW_SHOW);
|
|
|
|
return pNavFrame;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// void CNSNavFrame::StartDrag(CPoint pt)
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
|
|
void CNSNavFrame::StartDrag(CPoint pt, BOOL mapDesktop)
|
|
{
|
|
GetWindowRect(&m_dockingDragRect);
|
|
CPoint cursorPt(pt);
|
|
|
|
if (mapDesktop)
|
|
MapWindowPoints(NULL, &cursorPt, 1); // Convert the point to screen coords.
|
|
|
|
CRDFOutliner* pOutliner = (CRDFOutliner*)(GetContentView()->GetOutlinerParent()->GetOutliner());
|
|
|
|
if (XP_IsNavCenterDocked(GetHTPane()) || pOutliner->IsPopup())
|
|
{
|
|
pOutliner->SetIsPopup(FALSE);
|
|
ForceFloat(FALSE);
|
|
}
|
|
else ShowWindow(SW_HIDE);
|
|
|
|
m_bDragging = TRUE;
|
|
InitLoop();
|
|
|
|
m_rectDrag = m_rectFloat;
|
|
|
|
CNSGenFrame* pFrame = NULL;
|
|
CFrameGlue *pGlue = CFrameGlue::GetLastActiveFrame(MWContextBrowser, FEU_FINDBROWSERANDEDITOR);
|
|
CFrameWnd *pBaseWnd = pGlue->GetFrameWnd();
|
|
if(pBaseWnd && pBaseWnd->IsKindOf(RUNTIME_CLASS(CNSGenFrame)))
|
|
{
|
|
pFrame = (CNSGenFrame *)pBaseWnd;
|
|
}
|
|
CalcClientArea(&m_parentRect, pFrame);
|
|
pFrame->MapWindowPoints( NULL, &m_parentRect);
|
|
|
|
// Cache the offset that we wish to preserve.
|
|
m_nXOffset = cursorPt.x - m_dockingDragRect.left;
|
|
m_nYOffset = cursorPt.y - m_dockingDragRect.top;
|
|
|
|
// Compute the pixel sizes of vertically and horizontally docked windows
|
|
ComputeDockingSizes();
|
|
|
|
// initialize tracking state and enter tracking loop
|
|
Move(cursorPt); // call it here to handle special keys
|
|
Track();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// void CNSNavFrame::Move(CPoint pt)
|
|
// called when we get WM_MOUSEMOVE message.
|
|
//------------------------------------------------------------------------------
|
|
|
|
void CNSNavFrame::Move(CPoint pt) // called when mouse has moved
|
|
{
|
|
short dwOverDockStyle = CanDock(pt);
|
|
m_dockingDragRect = m_parentRect;
|
|
|
|
if (dwOverDockStyle == DOCKSTYLE_DOCKEDLEFT)
|
|
{
|
|
int height = m_dockingDragRect.Height();
|
|
m_dockingDragRect.right = m_dockingDragRect.left + m_DockWidth;
|
|
int yOffset = m_nYOffset;
|
|
if (yOffset > height)
|
|
yOffset = height;
|
|
m_dockingDragRect.top = pt.y - yOffset;
|
|
m_dockingDragRect.bottom = m_dockingDragRect.top + height;
|
|
}
|
|
else
|
|
{
|
|
int height = m_rectDrag.Height();
|
|
int width = m_rectDrag.Width();
|
|
int xOffset = m_nXOffset;
|
|
int yOffset = m_nYOffset;
|
|
if (xOffset > width)
|
|
xOffset = width;
|
|
if (yOffset > height)
|
|
yOffset = height;
|
|
|
|
m_rectDrag.left = pt.x - m_nXOffset;
|
|
m_rectDrag.top = pt.y - m_nYOffset;
|
|
m_rectDrag.bottom = m_rectDrag.top + height;
|
|
m_rectDrag.right = m_rectDrag.left + width;
|
|
}
|
|
|
|
DrawFocusRect(dwOverDockStyle);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// static BOOL nsModifyStyle(HWND hWnd, int nStyleOffset,
|
|
// DWORD dwRemove, DWORD dwAdd, UINT nFlags)
|
|
//------------------------------------------------------------------------------
|
|
|
|
BOOL nsModifyStyle(HWND hWnd, int nStyleOffset, DWORD dwRemove, DWORD dwAdd, UINT nFlags)
|
|
{
|
|
ASSERT(hWnd != NULL);
|
|
DWORD dwStyle = ::GetWindowLong(hWnd, nStyleOffset);
|
|
DWORD dwNewStyle = dwStyle;
|
|
if (dwRemove != NULL)
|
|
dwNewStyle = dwStyle & ~dwRemove;
|
|
if (dwAdd != NULL)
|
|
dwNewStyle = dwNewStyle | dwAdd;
|
|
if (dwStyle == dwNewStyle)
|
|
return FALSE;
|
|
|
|
::SetWindowLong(hWnd, nStyleOffset, dwNewStyle);
|
|
if (nFlags != 0)
|
|
{
|
|
::SetWindowPos(hWnd, NULL, 0, 0, 0, 0,
|
|
SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | nFlags);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// void CNSNavFrame::CalcClientArea(RECT* lpRectClient)
|
|
//
|
|
// The function will return the the client area of CMainFrame minus any of the spaces
|
|
// occupied by the tool bar.
|
|
//------------------------------------------------------------------------------
|
|
|
|
void CNSNavFrame::CalcClientArea(RECT* lpRectClient, CNSGenFrame * pParentFrame)
|
|
{
|
|
|
|
AFX_SIZEPARENTPARAMS layout;
|
|
HWND hWndLeftOver = NULL;
|
|
#ifdef XP_WIN32
|
|
layout.bStretch = FALSE;
|
|
layout.sizeTotal.cx = layout.sizeTotal.cy = 0;
|
|
#endif
|
|
CNSGenFrame* pFrame = NULL;
|
|
if (pParentFrame == NULL) {
|
|
CFrameGlue *pGlue = CFrameGlue::GetLastActiveFrame(MWContextBrowser, FEU_FINDBROWSERANDEDITOR);
|
|
CFrameWnd *pBaseWnd = pGlue->GetFrameWnd();
|
|
if(pBaseWnd && pBaseWnd->IsKindOf(RUNTIME_CLASS(CNSGenFrame))) {
|
|
pFrame = (CNSGenFrame *)pBaseWnd;
|
|
}
|
|
}
|
|
else {
|
|
pFrame = pParentFrame;
|
|
}
|
|
CNSNavFrame* pDockedFrame = pFrame->GetDockedNavCenter();
|
|
pFrame->GetClientRect(&layout.rect); // starting rect comes from client rect
|
|
CWnd *pView = pFrame->GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
|
|
HWND hWnd = pView->GetSafeHwnd();
|
|
layout.hDWP = NULL; // not actually doing layout
|
|
|
|
for (HWND hWndChild = ::GetTopWindow(pFrame->GetSafeHwnd()); hWndChild != NULL;
|
|
hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))
|
|
{
|
|
if (hWndChild != hWnd && hWndChild != GetSafeHwnd() && hWndChild != pDockedFrame->GetSafeHwnd())
|
|
::SendMessage(hWndChild, WM_SIZEPARENT, 0, (LPARAM)&layout);
|
|
}
|
|
lpRectClient->left = layout.rect.left;
|
|
lpRectClient->right = layout.rect.right;
|
|
lpRectClient->top = layout.rect.top;
|
|
lpRectClient->bottom = layout.rect.bottom;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// void CNSNavFrame::ForceFloat()
|
|
// Force this frame to be a floated frame.
|
|
//------------------------------------------------------------------------------
|
|
void CNSNavFrame::ForceFloat(BOOL show)
|
|
{
|
|
CFrameWnd *pLayout = GetParentFrame();
|
|
|
|
nsModifyStyle( GetSafeHwnd(), GWL_STYLE, WS_CHILD, WS_OVERLAPPEDWINDOW);
|
|
nsModifyStyle( GetSafeHwnd(), GWL_EXSTYLE, 0, WS_EX_CLIENTEDGE);
|
|
|
|
if (show)
|
|
{
|
|
MoveWindow( m_rectDrag);
|
|
}
|
|
else ShowWindow(SW_HIDE);
|
|
|
|
SetParent(NULL);
|
|
|
|
if (m_DragWnd)
|
|
{
|
|
m_DragWnd->DestroyWindow();
|
|
m_DragWnd = NULL;
|
|
}
|
|
|
|
m_dwOverDockStyle = DOCKSTYLE_FLOATING;
|
|
|
|
if (show)
|
|
ShowWindow(SW_SHOW);
|
|
else ShowWindow(SW_HIDE);
|
|
|
|
// Tell XP NavCenter layer that we are no longer docked.
|
|
XP_UndockNavCenter(GetHTPane());
|
|
|
|
// Tell ParentFrame that we are not docked anymore.
|
|
if (pLayout)
|
|
pLayout->RecalcLayout();
|
|
|
|
}
|
|
|
|
void CNSNavFrame::ComputeDockingSizes()
|
|
{
|
|
m_DockWidth = m_DockSize + 1; // Not sure what the error is here yet.
|
|
m_DockHeight = m_DockSize + 1;
|
|
}
|
|
|
|
|
|
void CNSNavFrame::DockFrame(CNSGenFrame* pParent, short dockStyle)
|
|
{
|
|
CWnd *pView = pParent->GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
|
|
CalcClientArea(&m_parentRect, pParent);
|
|
ComputeDockingSizes();
|
|
|
|
if (GetHTPane() == NULL || XP_IsNavCenterDocked(GetHTPane()) == FALSE)
|
|
{
|
|
CNSNavFrame* pFrame = pParent->GetDockedNavCenter();
|
|
if (pFrame)
|
|
{ // if the parent frame has a docked frame, then destroy it.
|
|
pFrame->DeleteNavCenter();
|
|
}
|
|
nsModifyStyle( GetSafeHwnd(), GWL_STYLE, WS_OVERLAPPEDWINDOW, WS_CHILD);
|
|
nsModifyStyle( GetSafeHwnd(), GWL_EXSTYLE, WS_EX_CLIENTEDGE, 0);
|
|
nsModifyStyle( GetSafeHwnd(), GWL_STYLE, WS_POPUP, 0);
|
|
|
|
SetParent(pParent);
|
|
|
|
// Tell XP layer that we are now docked.
|
|
if(GetTopLevelFrame())
|
|
{
|
|
CFrameGlue *pGlue = CFrameGlue::GetFrameGlue(GetTopLevelFrame());
|
|
if(pGlue && pGlue->GetMainContext()) {
|
|
XP_DockNavCenter(GetHTPane(), pGlue->GetMainContext()->GetContext());
|
|
}
|
|
}
|
|
|
|
// Notify HT of our new state.
|
|
HT_SetTreeStateForButton(HT_TopNode(HT_GetSelectedView(GetHTPane())), "Docked");
|
|
|
|
CRect rect = m_dockingDragRect;
|
|
|
|
// Hide the window before we move it.
|
|
m_dwOverDockStyle = dockStyle;
|
|
if (m_dwOverDockStyle == DOCKSTYLE_DOCKEDLEFT)
|
|
{
|
|
GetDesktopWindow()->MapWindowPoints( pView, &rect );
|
|
|
|
// snap to right, when the drag rect is closer to the right edge.
|
|
if (rect.right > ((m_parentRect.right - m_parentRect.left) / 2))
|
|
{
|
|
rect.right = m_parentRect.right;
|
|
rect.left = rect.right - m_DockWidth;
|
|
}
|
|
else { // otherwise snap to the left.
|
|
rect.left = m_parentRect.left;
|
|
rect.right = rect.left + m_DockWidth;
|
|
}
|
|
rect.top = m_parentRect.top;
|
|
rect.bottom = m_parentRect.bottom;
|
|
}
|
|
else
|
|
{
|
|
GetDesktopWindow()->MapWindowPoints( pView, &rect );
|
|
// snap to bottom, when the drag rect is closer to the bottom edge.
|
|
if (rect.bottom > ((m_parentRect.bottom - m_parentRect.top) / 2))
|
|
{
|
|
rect.bottom = m_parentRect.bottom;
|
|
rect.top = rect.bottom - m_DockHeight;
|
|
}
|
|
else { // otherwise snap to the left.
|
|
rect.top = m_parentRect.top;
|
|
rect.bottom = rect.top + m_DockHeight;
|
|
}
|
|
rect.left = m_parentRect.left;
|
|
rect.right = m_parentRect.right;
|
|
}
|
|
|
|
// Figure out the correct location to display the resize bar.
|
|
CRect dragBarRect(rect);
|
|
if (m_dwOverDockStyle == DOCKSTYLE_DOCKEDLEFT)
|
|
{
|
|
dragBarRect.left = rect.right;
|
|
dragBarRect.right = dragBarRect.left+ DRAGWIDTH;
|
|
}
|
|
|
|
if (!m_DragWnd)
|
|
{
|
|
m_DragWnd = new CDragBar(dragBarRect, this);
|
|
m_DragWnd->CreateEx(0, NULL, "GridEdge", WS_CHILD | WS_VISIBLE,
|
|
dragBarRect.left, dragBarRect.top,
|
|
dragBarRect.right - dragBarRect.left,
|
|
dragBarRect.bottom - dragBarRect.top,
|
|
GetParentFrame()->GetSafeHwnd(), (HMENU)NC_IDW_DRAGEDGE, NULL);
|
|
}
|
|
// If we are not yet docked
|
|
m_DragWnd->SetOrientation(m_dwOverDockStyle);
|
|
m_DragWnd->SetParentFrame(GetParentFrame());
|
|
m_DragWnd->SetRect(dragBarRect);
|
|
m_DragWnd->SetParent(GetParentFrame());
|
|
|
|
// Now move the window to the correct location.
|
|
ShowWindow(SW_HIDE);
|
|
SetWindowPos( &wndBottom, rect.left, rect.top, rect.right - rect.left,
|
|
rect.bottom - rect.top,0 );
|
|
|
|
ShowWindow(SW_SHOW);
|
|
}
|
|
|
|
// Have our frame parent recalc.
|
|
GetParentFrame()->RecalcLayout();
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
// void CNSNavFrame::EndDrag(CPoint pt) // drop
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
void CNSNavFrame::EndDrag(CPoint pt) // drop
|
|
{
|
|
short dwOverDockStyle = CanDock(pt);
|
|
CancelLoop(dwOverDockStyle);
|
|
CRect rect;
|
|
CRect parentRect;
|
|
|
|
if (dwOverDockStyle == DOCKSTYLE_DOCKEDLEFT)
|
|
{
|
|
CNSGenFrame* pFrame = NULL;
|
|
CFrameGlue *pGlue = CFrameGlue::GetLastActiveFrame(MWContextBrowser, FEU_FINDBROWSERANDEDITOR);
|
|
CFrameWnd *pBaseWnd = pGlue->GetFrameWnd();
|
|
if(pBaseWnd && pBaseWnd->IsKindOf(RUNTIME_CLASS(CNSGenFrame)))
|
|
{
|
|
pFrame = (CNSGenFrame *)pBaseWnd;
|
|
}
|
|
DockFrame(pFrame, dwOverDockStyle);
|
|
// m_nsContent->CalcChildSizes();
|
|
}
|
|
else
|
|
{
|
|
// Float this frame.
|
|
MoveWindow( m_rectDrag);
|
|
|
|
// If it had a button associated with it, now it doesn't.
|
|
UnhookFromButton();
|
|
}
|
|
|
|
ShowWindow(SW_SHOW);
|
|
}
|
|
|
|
|
|
void CNSNavFrame::InitLoop()
|
|
{
|
|
// 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);
|
|
}
|
|
|
|
|
|
// initialize state
|
|
m_rectLast.SetRectEmpty();
|
|
m_sizeLast.cx = m_sizeLast.cy = 0;
|
|
m_bDitherLast = FALSE;
|
|
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 CNSNavFrame::CancelLoop(short dwDockStyle)
|
|
{
|
|
DrawFocusRect(dwDockStyle, TRUE); // gets rid of focus rect
|
|
ReleaseCapture();
|
|
|
|
CWnd* pWnd = CWnd::GetDesktopWindow();
|
|
#ifdef XP_WIN32
|
|
pWnd->UnlockWindowUpdate();
|
|
#else
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
::LockWindowUpdate(NULL);
|
|
#endif
|
|
if (m_pDC != NULL)
|
|
{
|
|
pWnd->ReleaseDC(m_pDC);
|
|
m_pDC = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// void CNSNavFrame::DrawFocusRect(BOOL bRemoveRect)
|
|
//
|
|
// Draw ghost selector rect.
|
|
//---------------------------------------------------------------------------------
|
|
void CNSNavFrame::DrawFocusRect(short dwOverDockStyle, BOOL bRemoveRect)
|
|
{
|
|
ASSERT(m_pDC != NULL);
|
|
|
|
// default to thin frame
|
|
CSize size(CX_BORDER, CY_BORDER);
|
|
|
|
// determine new rect and size
|
|
CRect rect;
|
|
CBrush* pWhiteBrush = CBrush::FromHandle((HBRUSH)::GetStockObject(WHITE_BRUSH));
|
|
CBrush* pBrush = pWhiteBrush;
|
|
if (dwOverDockStyle == DOCKSTYLE_DOCKEDLEFT)
|
|
{
|
|
rect = m_dockingDragRect;
|
|
}
|
|
else
|
|
{
|
|
rect = m_rectDrag;
|
|
}
|
|
if (bRemoveRect)
|
|
size.cx = size.cy = 0;
|
|
|
|
CBrush* pDitherBrush = CDC::GetHalftoneBrush();
|
|
|
|
// draw it and remember last size
|
|
WFE_DrawDragRect(m_pDC, &rect, size, &m_rectLast, m_sizeLast,
|
|
pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush);
|
|
m_bDitherLast = (pBrush == pDitherBrush);
|
|
m_rectLast = rect;
|
|
m_sizeLast = size;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------------
|
|
// short CNSNavFrame::CanDock(CPoint pt)
|
|
// Check whether we can dock to this frame. If we can, return the dock orientation.
|
|
//---------------------------------------------------------------------------------
|
|
short CNSNavFrame::CanDock(CPoint pt, BOOL mapDesktop)
|
|
{
|
|
short dockStyle = DOCKSTYLE_FLOATING;
|
|
|
|
CNSGenFrame* pFrame = NULL;
|
|
CFrameGlue *pGlue = CFrameGlue::GetLastActiveFrame(MWContextBrowser, FEU_FINDBROWSERANDEDITOR);
|
|
CFrameWnd *pBaseWnd = pGlue->GetFrameWnd();
|
|
if(pBaseWnd && pBaseWnd->IsKindOf(RUNTIME_CLASS(CNSGenFrame))) {
|
|
pFrame = (CNSGenFrame *)pBaseWnd;
|
|
}
|
|
|
|
if (mapDesktop) {
|
|
|
|
CWnd *pView = pFrame->GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
|
|
if (XP_IsNavCenterDocked(GetHTPane())) {
|
|
MapWindowPoints( pView, &pt, 1 );
|
|
pView->MapWindowPoints( GetDesktopWindow(), &pt, 1 );
|
|
}
|
|
else
|
|
MapWindowPoints( GetDesktopWindow(), &pt, 1 );
|
|
}
|
|
|
|
// If the top most activated frame is not a Navigator window, do not dock.
|
|
if (pFrame->AllowDocking()) {
|
|
if (m_parentRect.PtInRect(pt)) {
|
|
if ((pt.x < (m_parentRect.left +m_DockWidth)) &&
|
|
pt.x > m_parentRect.left)
|
|
dockStyle = DOCKSTYLE_DOCKEDLEFT;
|
|
}
|
|
}
|
|
else {
|
|
dockStyle = DOCKSTYLE_FLOATING;
|
|
}
|
|
|
|
return dockStyle;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Track mouse movement after the LMouseDown.
|
|
//------------------------------------------------------------------------------
|
|
|
|
BOOL CNSNavFrame::Track()
|
|
{
|
|
// don't handle if capture already set
|
|
if (::GetCapture() != NULL)
|
|
return FALSE;
|
|
|
|
// set capture to the window which received this message
|
|
SetCapture();
|
|
|
|
// get messages until capture is lost or cancelled/accepted
|
|
while (CWnd::GetCapture() == this) {
|
|
MSG msg;
|
|
if (!::GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
#ifdef XP_WIN32
|
|
AfxPostQuitMessage(msg.wParam);
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
switch (msg.message)
|
|
{
|
|
case WM_LBUTTONUP:
|
|
if (m_bDragging)
|
|
m_bDragging = FALSE;
|
|
EndDrag(msg.pt);
|
|
return TRUE;
|
|
case WM_MOUSEMOVE:
|
|
if (m_bDragging)
|
|
Move(msg.pt);
|
|
break;
|
|
// just dispatch rest of the messages
|
|
default:
|
|
DispatchMessage(&msg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// LRESULT CNSNavFrame::OnSizeParent(WPARAM, LPARAM lParam)
|
|
//
|
|
// This function will be called when the parent window calls recalcLayout().
|
|
// It will subtract this window's client rect from lpLayout. Parent uses this
|
|
// function to layout other window in the left over lpLayout.
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
|
|
LRESULT CNSNavFrame::OnSizeParent(WPARAM, LPARAM lParam)
|
|
{
|
|
AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
|
|
|
|
// dragRect is in the parent window's coordinates(which is the main frame).
|
|
// the top and bottom coordinates of the dragRect should already be included
|
|
// in the toolbar.
|
|
|
|
if (!m_DragWnd) return 0;
|
|
|
|
CRect oldRect;
|
|
GetWindowRect(&oldRect);
|
|
CRect resizeRect(lpLayout->rect);
|
|
CRect oldDragRect;
|
|
m_DragWnd->GetRect(oldDragRect);
|
|
|
|
CRect dragRect(resizeRect);
|
|
|
|
if (m_dwOverDockStyle == DOCKSTYLE_DOCKEDLEFT)
|
|
{
|
|
resizeRect.right = lpLayout->rect.left + oldRect.Width();
|
|
if (oldDragRect.left != resizeRect.right) // we move the drag bar. Need to resize here.
|
|
resizeRect.right += oldDragRect.left - resizeRect.right;
|
|
|
|
CWnd* pParent = GetParent();
|
|
CRect parentRect;
|
|
pParent->GetClientRect(&parentRect);
|
|
|
|
if (parentRect.Width() < resizeRect.Width() + DRAGWIDTH)
|
|
{
|
|
resizeRect.right = resizeRect.left + parentRect.Width() - DRAGWIDTH;
|
|
}
|
|
|
|
dragRect.left = resizeRect.right;
|
|
dragRect.right = dragRect.left + DRAGWIDTH;
|
|
|
|
lpLayout->rect.left = resizeRect.right + DRAGWIDTH;
|
|
|
|
m_DragWnd->SetRect(dragRect);
|
|
m_DockWidth = resizeRect.Width();
|
|
}
|
|
|
|
if (lpLayout->hDWP != NULL) {
|
|
// reposition our frame window.
|
|
SetWindowPos( &wndBottom, resizeRect.left, resizeRect.top, resizeRect.right - resizeRect.left,
|
|
resizeRect.bottom - resizeRect.top, SWP_SHOWWINDOW );
|
|
m_dockingDragRect = resizeRect;
|
|
|
|
m_DragWnd->SetWindowPos( &wndBottom, dragRect.left, dragRect.top, dragRect.Width(),
|
|
dragRect.Height(), SWP_SHOWWINDOW );
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void FillSolidRect(HDC hdc, RECT* rect, COLORREF clr)
|
|
{
|
|
::SetBkColor(hdc, clr);
|
|
::ExtTextOut(hdc, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CNSNavFrame diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CNSNavFrame::AssertValid() const
|
|
{
|
|
CFrameWnd::AssertValid();
|
|
}
|
|
|
|
void CNSNavFrame::Dump(CDumpContext& dc) const
|
|
{
|
|
CFrameWnd::Dump(dc);
|
|
}
|
|
|
|
#endif //_DEBUG
|
|
|
|
HT_Pane CNSNavFrame::GetHTPane()
|
|
{
|
|
if(m_Node)
|
|
return HT_GetPane(HT_GetView(m_Node));
|
|
return NULL;
|
|
}
|
|
|
|
void CNSNavFrame::OnNcLButtonDown( UINT nHitTest, CPoint point )
|
|
{
|
|
if (nHitTest == HTCAPTION)
|
|
{
|
|
m_ptLast = point;
|
|
SetCapture();
|
|
}
|
|
|
|
CWnd::OnNcLButtonDown(nHitTest, point);
|
|
}
|
|
|
|
void CNSNavFrame::OnLButtonUp( UINT nHitTest, CPoint point )
|
|
{
|
|
if (GetCapture() == this)
|
|
{
|
|
ReleaseCapture();
|
|
}
|
|
|
|
CWnd::OnNcLButtonUp(nHitTest, point);
|
|
}
|
|
|
|
void CNSNavFrame::OnMouseMove( UINT nHitTest, CPoint point )
|
|
{
|
|
if (GetCapture() == this)
|
|
{
|
|
MapWindowPoints(NULL, &point, 1);
|
|
if (abs(point.x - m_ptLast.x) > 3 ||
|
|
abs(point.y - m_ptLast.y) > 3)
|
|
{
|
|
ReleaseCapture();
|
|
StartDrag(point, FALSE);
|
|
}
|
|
}
|
|
|
|
CWnd::OnNcMouseMove(nHitTest, point);
|
|
}
|
|
|