зеркало из https://github.com/mozilla/gecko-dev.git
1345 строки
36 KiB
C++
1345 строки
36 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.
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "navfram.h"
|
|
#include "feimage.h"
|
|
#include "net.h"
|
|
#include "cxsave.h"
|
|
#include "cxicon.h"
|
|
#include "fegui.h"
|
|
#include "rdfliner.h"
|
|
#include "mmsystem.h"
|
|
#include "winproto.h"
|
|
#include "xp_ncent.h"
|
|
#include "pain.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
#ifndef _AFXDLL
|
|
#undef new
|
|
#endif
|
|
|
|
#ifndef _AFXDLL
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
#include "dropmenu.h"
|
|
|
|
//////////////////////////
|
|
// RDF Event Handlers
|
|
|
|
// The Main Event Handler for the NavCenter. Handles events on the selector bar AND within the tree
|
|
// views.
|
|
void notifyProcedure (HT_Notification ns, HT_Resource n, HT_Event whatHappened)
|
|
{
|
|
CSelector* theSelector = (CSelector*)ns->data;
|
|
if (theSelector == NULL)
|
|
return;
|
|
|
|
HT_View theView = HT_GetView(n);
|
|
|
|
// The pane has to handle some events. These will go here.
|
|
if (whatHappened == HT_EVENT_VIEW_SELECTED)
|
|
{
|
|
CView* pView = theSelector->GetCurrentView();
|
|
CSelectorButton* pButton = theSelector->GetCurrentButton();
|
|
|
|
// If the new selected view is NULL, then we need to make sure our pane is closed.
|
|
if (theView == NULL && pView != NULL)
|
|
{
|
|
// We're open. Close the pane.
|
|
((CNSNavFrame*)theSelector->GetParentFrame())->CollapseWindow();
|
|
}
|
|
else if (theView != NULL)
|
|
{
|
|
// We have a view. Select it.
|
|
CSelectorButton* pButton = (CSelectorButton*)HT_GetViewFEData(theView);
|
|
theSelector->SetCurrentView(pButton);
|
|
|
|
if (pView == NULL)
|
|
{
|
|
// Need to open the pane.
|
|
((CNSNavFrame*)theSelector->GetParentFrame())->ExpandWindow();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (theView == NULL)
|
|
return;
|
|
|
|
if (whatHappened == HT_EVENT_VIEW_ADDED)
|
|
{
|
|
theSelector->ConstructView(theView);
|
|
theSelector->RearrangeIcons();
|
|
CSelectorButton* pButton = (CSelectorButton*)HT_GetViewFEData(theView);
|
|
}
|
|
else if (whatHappened == HT_EVENT_VIEW_DELETED)
|
|
{
|
|
// Delete the content view
|
|
CSelectorButton* pButton = (CSelectorButton*)HT_GetViewFEData(theView);
|
|
if (pButton)
|
|
{
|
|
pButton->GetView()->DestroyWindow();
|
|
|
|
// Delete the button
|
|
delete pButton;
|
|
|
|
// Remove our FE data
|
|
HT_SetViewFEData(theView, NULL);
|
|
}
|
|
}
|
|
else if (whatHappened == HT_EVENT_NODE_VPROP_CHANGED && HT_TopNode(theView) == n)
|
|
{
|
|
// Top level node changed its name/icon. Need to change the button text, window title bar, and
|
|
// embedded nav menu bar. Also need to update the current tree view and the column headers. (Whew!)
|
|
CSelectorButton* pButton = (CSelectorButton*)HT_GetViewFEData(theView);
|
|
if (pButton && pButton->m_hWnd)
|
|
{
|
|
// Invalidate the button.
|
|
pButton->Invalidate();
|
|
|
|
// Invalidate the title bar.
|
|
CFrameWnd* pFrame = pButton->GetParentFrame();
|
|
if (pFrame->IsKindOf(RUNTIME_CLASS(CNSNavFrame)))
|
|
{
|
|
CNSNavFrame* pNavFrame = (CNSNavFrame*)pFrame;
|
|
if (pNavFrame)
|
|
{
|
|
// Invalidate the title bar.
|
|
CNavMenuBar* pBar = pNavFrame->GetNavMenuBar();
|
|
if (pBar)
|
|
pBar->Invalidate();
|
|
|
|
// Invalidate the tree view.
|
|
CRDFContentView* theOutlinerView = (CRDFContentView*)pButton->GetTreeView();
|
|
if (theOutlinerView)
|
|
{
|
|
CRDFOutlinerParent* pParent = (CRDFOutlinerParent*)(theOutlinerView->GetOutlinerParent());
|
|
if (pParent)
|
|
{
|
|
pParent->Invalidate();
|
|
COutliner* pOutliner = pParent->GetOutliner();
|
|
if (pOutliner)
|
|
pOutliner->Invalidate();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (whatHappened == HT_EVENT_NODE_EDIT && HT_TopNode(theView) == n)
|
|
{
|
|
// Edit being performed on a selector bar item. (STILL TO DO)
|
|
}
|
|
else if (whatHappened == HT_EVENT_VIEW_WORKSPACE_REFRESH)
|
|
theSelector->RearrangeIcons(); // Redraw the selector.
|
|
|
|
// If the pane doesn't handle the event, then a view does.
|
|
else
|
|
{
|
|
// View needs to exist in order for us to send this event to it.
|
|
CSelectorButton* pButton = (CSelectorButton*)HT_GetViewFEData(theView);
|
|
if (pButton)
|
|
{
|
|
CRDFContentView* theOutlinerView = (CRDFContentView*)pButton->GetTreeView();
|
|
if (theOutlinerView)
|
|
{
|
|
CRDFOutliner* theOutliner = (CRDFOutliner*)(theOutlinerView->GetOutlinerParent()->GetOutliner());
|
|
theOutliner->HandleEvent(ns, n, whatHappened);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// The Event Handler for selector popup menus
|
|
static void selectorPopupNotifyProcedure (HT_Notification ns, HT_Resource n, HT_Event whatHappened)
|
|
{
|
|
// We respond only to open/closed events. This procedure is only entered when the user clicks
|
|
// and holds on a selector bar button to bring up a popup menu.
|
|
CSelectorButton* theButton = (CSelectorButton*)ns->data;
|
|
if (n != NULL)
|
|
{
|
|
HT_View theView = HT_GetView(n);
|
|
if (theView != NULL && (whatHappened == HT_EVENT_NODE_OPENCLOSE_CHANGED))
|
|
{
|
|
PRBool openState;
|
|
HT_GetOpenState(n, &openState);
|
|
if (openState)
|
|
{
|
|
theButton->FillInMenu(n);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// SelectorButton
|
|
|
|
CSelectorButton::~CSelectorButton()
|
|
{
|
|
if (m_Pane)
|
|
HT_DeletePane(m_Pane);
|
|
|
|
m_Node = NULL;
|
|
}
|
|
|
|
int CSelectorButton::Create(CWnd *pParent, int nToolbarStyle, CSize noviceButtonSize,
|
|
CSize advancedButtonSize,
|
|
LPCTSTR pButtonText, LPCTSTR pToolTipText,
|
|
LPCTSTR pStatusText,
|
|
CSize bitmapSize, int nMaxTextChars, int nMinTextChars,
|
|
HT_Resource pNode,
|
|
DWORD dwButtonStyle, CView* view, CPaneCX* pane)
|
|
{
|
|
pView = view;
|
|
m_pPane = pane;
|
|
|
|
// Construct the notification struct used by HT
|
|
HT_Notification ns = new HT_NotificationStruct;
|
|
ns->notifyProc = selectorPopupNotifyProcedure;
|
|
ns->data = this;
|
|
|
|
// Construct the pane and give it our notification struct
|
|
m_Pane = HT_PaneFromResource(HT_GetRDFResource(pNode), ns, (PRBool)TRUE);
|
|
HT_SetPaneFEData(m_Pane, this);
|
|
|
|
HT_Resource pEntry = NULL;
|
|
HT_View theView = HT_GetSelectedView(m_Pane);
|
|
|
|
BOOKMARKITEM bookmark; // For now, create with the pictures style. No text ever.
|
|
return CRDFToolbarButton::Create(pParent, TB_PICTURES, noviceButtonSize, advancedButtonSize,
|
|
pButtonText, pToolTipText, pStatusText, bitmapSize, nMaxTextChars, nMinTextChars,
|
|
bookmark, HT_TopNode(theView), dwButtonStyle);
|
|
}
|
|
|
|
void CSelectorButton::OnAction()
|
|
{
|
|
if (m_pDropMenu == NULL || !m_pDropMenu->IsOpen())
|
|
{
|
|
HT_Pane pane = HT_GetPane(m_HTView);
|
|
if (m_pSelector->GetCurrentButton() == this)
|
|
{
|
|
// View is already selected. We are now closing the pane.
|
|
HT_SetSelectedView(pane, NULL);
|
|
}
|
|
else HT_SetSelectedView(pane, m_HTView);
|
|
}
|
|
}
|
|
|
|
CSize CSelectorButton::GetButtonSizeFromChars(CString s, int c)
|
|
{
|
|
if (m_nToolbarStyle == TB_PICTURES)
|
|
return GetBitmapOnlySize();
|
|
else if(m_nToolbarStyle == TB_TEXT)
|
|
return(GetTextOnlySize(s, c));
|
|
else
|
|
return(GetBitmapOnTopSize(s, c));
|
|
}
|
|
|
|
|
|
void CSelectorButton::DrawPicturesMode(HDC hDC, CRect rect)
|
|
{
|
|
|
|
DrawButtonBitmap(hDC, rect);
|
|
|
|
}
|
|
|
|
void CSelectorButton::DrawPicturesAndTextMode(HDC hDC, CRect rect)
|
|
{
|
|
//DrawBitmapOnTop(hDC, rect);
|
|
DrawButtonBitmap(hDC, rect);
|
|
}
|
|
|
|
void CSelectorButton::GetPicturesAndTextModeTextRect(CRect &rect)
|
|
{
|
|
//GetBitmapOnTopTextRect(rect);
|
|
GetPicturesModeTextRect(rect);
|
|
}
|
|
|
|
void CSelectorButton::GetPicturesModeTextRect(CRect &rect)
|
|
{
|
|
//GetBitmapOnTopTextRect(rect);
|
|
CToolbarButton::GetPicturesModeTextRect(rect);
|
|
}
|
|
|
|
void CSelectorButton::DisplayMenuOnDrag()
|
|
{
|
|
CPoint point = RequestMenuPlacement();
|
|
|
|
if(m_pDropMenu == NULL || !m_pDropMenu->IsOpen())
|
|
{
|
|
int nCount;
|
|
if(m_pDropMenu != NULL)
|
|
{
|
|
nCount = m_pDropMenu->GetMenuItemCount();
|
|
|
|
// clean out the menu before adding to it
|
|
for(int i = nCount - 1; i >= 0; i--)
|
|
{
|
|
m_pDropMenu->DeleteMenu(i, MF_BYPOSITION);
|
|
}
|
|
m_pDropMenu->DestroyDropMenu();
|
|
delete m_pDropMenu;
|
|
}
|
|
|
|
m_pDropMenu = new CDropMenu;
|
|
SendMessage(NSDRAGMENUOPEN, (WPARAM)GetButtonCommand(), (LPARAM)m_pDropMenu);
|
|
|
|
nCount = m_pDropMenu->GetMenuItemCount();
|
|
|
|
if(nCount > 0)
|
|
{
|
|
CDropMenuDropTarget *dropTarget = new CDropMenuDropTarget(m_pDropMenu);
|
|
m_pDropMenu->TrackDropMenu(this, point.x, point.y, TRUE, dropTarget, TRUE);
|
|
}
|
|
else
|
|
{
|
|
CDropMenu* theLastMenu = CDropMenu::GetLastDropMenu();
|
|
if(theLastMenu !=NULL)
|
|
{
|
|
//we only want one drop menu open at a time, so close the last one if one is
|
|
//still open.
|
|
theLastMenu->Deactivate();
|
|
CDropMenu::SetLastDropMenu(NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CSelectorButton::CreateRightMouseMenu()
|
|
{
|
|
// Selector buttons should be selected if the tree is visible.
|
|
if (m_pSelector->IsTreeVisible())
|
|
{
|
|
// Actually switch to this view.
|
|
if (!m_bDepressed)
|
|
{
|
|
// Depress.
|
|
OnAction();
|
|
}
|
|
}
|
|
|
|
// Build the actual menu.
|
|
m_MenuCommandMap.Clear();
|
|
|
|
HT_Cursor theCursor = HT_NewContextualMenuCursor(m_HTView, PR_TRUE, PR_FALSE);
|
|
if (theCursor != NULL)
|
|
{
|
|
// We have a cursor. Attempt to iterate
|
|
HT_MenuCmd theCommand;
|
|
while (HT_NextContextMenuItem(theCursor, &theCommand))
|
|
{
|
|
char* menuName = HT_GetMenuCmdName(theCommand);
|
|
if (theCommand == HT_CMD_SEPARATOR)
|
|
m_menu.AppendMenu(MF_SEPARATOR);
|
|
else
|
|
{
|
|
// Add the command to our command map
|
|
CRDFMenuCommand* rdfCommand = new CRDFMenuCommand(menuName, theCommand);
|
|
int index = m_MenuCommandMap.AddCommand(rdfCommand);
|
|
m_menu.AppendMenu(MF_ENABLED, index+FIRST_HT_MENU_ID, menuName);
|
|
}
|
|
}
|
|
HT_DeleteCursor(theCursor);
|
|
}
|
|
return TRUE;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CNavCenterFrame
|
|
|
|
//IMPLEMENT_DYNAMIC(CSelector, CScrollView)
|
|
IMPLEMENT_DYNAMIC(CSelector, CView)
|
|
BEGIN_MESSAGE_MAP(CSelector, CView)
|
|
//{{AFX_MSG_MAP(CMainFrame)
|
|
// 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_MOUSEMOVE()
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_PARENTNOTIFY()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_TIMER()
|
|
ON_MESSAGE(NSBUTTONDRAGGING, OnButtonDrag)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
CSelector::CSelector()
|
|
{
|
|
m_pCurView = NULL;
|
|
m_xpos = ICONXPOS;
|
|
m_ypos = ICONYPOS;
|
|
m_pDropTarget = NULL;
|
|
m_Pane = NULL;
|
|
m_Notification = NULL;
|
|
m_scrollPos = 0;
|
|
m_pCurButton = NULL;
|
|
m_boundingBox.SetRectEmpty();
|
|
m_hScrollBmp = ::LoadBitmap( AfxGetResourceHandle(),
|
|
MAKEINTRESOURCE( IDB_VFLIPPY ));
|
|
BITMAP bm;
|
|
::GetObject( m_hScrollBmp, sizeof( bm ), &bm );
|
|
m_hScrollBmpSize.cx = bm.bmWidth / 4;
|
|
m_hScrollBmpSize.cy = bm.bmHeight;
|
|
m_scrollUp = new CNavSelScrollButton(m_hScrollBmp, m_hScrollBmpSize.cx, 0, m_hScrollBmpSize.cy);
|
|
m_scrollDown = new CNavSelScrollButton(m_hScrollBmp, m_hScrollBmpSize.cx, 2, m_hScrollBmpSize.cy);
|
|
m_scrollDirection = NOSCROLL;
|
|
|
|
m_hPaneSwitchTimer = 0;
|
|
}
|
|
|
|
CSelector::~CSelector()
|
|
{
|
|
if (m_hScrollBmp)
|
|
{
|
|
VERIFY( ::DeleteObject( m_hScrollBmp ));
|
|
}
|
|
|
|
if (m_Pane != NULL)
|
|
{
|
|
int count = HT_GetViewListCount(m_Pane);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
HT_View view = HT_GetNthView(m_Pane, i);
|
|
|
|
if (view && HT_GetViewFEData(view))
|
|
{
|
|
CSelectorButton* theButton = (CSelectorButton*)HT_GetViewFEData(view);
|
|
delete theButton;
|
|
HT_SetViewFEData(view, NULL);
|
|
}
|
|
}
|
|
|
|
XP_UnregisterNavCenter(m_Pane);
|
|
HT_DeletePane(m_Pane);
|
|
}
|
|
|
|
if (m_scrollUp)
|
|
delete m_scrollUp;
|
|
if (m_scrollDown)
|
|
delete m_scrollDown;
|
|
|
|
delete m_Notification;
|
|
if(m_pDropTarget)
|
|
{
|
|
m_pDropTarget->Revoke();
|
|
delete m_pDropTarget;
|
|
m_pDropTarget = NULL;
|
|
}
|
|
}
|
|
|
|
void CSelector::OnDraw(CDC* pDC)
|
|
{
|
|
}
|
|
|
|
int CSelector::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if(!m_pDropTarget) {
|
|
m_pDropTarget = new CSelectorDropTarget(this);
|
|
m_pDropTarget->Register(this);
|
|
}
|
|
CRect tempRect(0, 0, 1, 1);
|
|
m_scrollUp->Create("", BS_OWNERDRAW | BS_PUSHBUTTON , tempRect, this, SCROLLID);
|
|
m_scrollDown->Create("", BS_OWNERDRAW | BS_PUSHBUTTON , tempRect, this, SCROLLID+1);
|
|
m_scrollUp->SetWindowPos( &wndTopMost, 0, 0, 1, 1, 0);
|
|
m_scrollDown->SetWindowPos( &wndTopMost, 0, 0, 1, 1, 0);
|
|
|
|
#ifdef XP_WIN32
|
|
::SetClassLong(GetSafeHwnd(), GCL_HBRBACKGROUND, (COLOR_BTNFACE + 1));
|
|
#else
|
|
::SetClassWord(GetSafeHwnd(), GCW_HBRBACKGROUND, (COLOR_BTNFACE + 1));
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CSelector::SelectNthView(int i)
|
|
{
|
|
HT_View theView = HT_GetNthView(m_Pane, i);
|
|
if (theView && HT_GetViewFEData(theView))
|
|
{
|
|
CSelectorButton* pButton = (CSelectorButton*)HT_GetViewFEData(theView);
|
|
pButton->OnAction();
|
|
}
|
|
}
|
|
|
|
BOOL CSelector::IsTreeVisible()
|
|
{
|
|
return m_pCurView != NULL;
|
|
}
|
|
|
|
void CSelector::SetCurrentView(CSelectorButton* pButton)
|
|
{
|
|
CView* pView = pButton->GetView();
|
|
|
|
if (m_pCurButton)
|
|
{
|
|
m_pCurButton->SetDepressed(FALSE);
|
|
}
|
|
m_pCurButton = pButton;
|
|
m_pCurButton->SetDepressed(TRUE);
|
|
if (m_pCurView != pView )
|
|
{
|
|
if (m_pCurView)
|
|
m_pCurView->ShowWindow(SW_HIDE);
|
|
m_pCurView = pView;
|
|
GetParentFrame()->SetActiveView( m_pCurView);
|
|
|
|
((CNSNavFrame*)GetParentFrame())->GetNavMenuBar()->UpdateView(m_pCurButton, m_pCurButton->GetHTView());
|
|
((CNSNavFrame*)GetParentFrame())->UpdateTitleBar(m_pCurButton->GetHTView());
|
|
}
|
|
|
|
// adjust the window. here.
|
|
m_pCurView->ShowWindow(SW_SHOW);
|
|
if(m_pCurView->GetParent()->IsKindOf(RUNTIME_CLASS(CContentView)))
|
|
{
|
|
CContentView* contentView = (CContentView*)m_pCurView->GetParent();
|
|
contentView->CalcChildSizes();
|
|
}
|
|
|
|
m_pCurView->SetFocus();
|
|
}
|
|
|
|
void CSelector::UnSelectAll()
|
|
{
|
|
if (m_pCurButton)
|
|
m_pCurButton->SetDepressed(FALSE);
|
|
m_pCurButton = 0;
|
|
if (m_pCurView)
|
|
{
|
|
m_pCurView->ShowWindow(SW_HIDE);
|
|
m_pCurView = 0;
|
|
GetParentFrame()->SetActiveView( m_pCurView);
|
|
}
|
|
|
|
((CNSNavFrame*)GetParentFrame())->GetNavMenuBar()->UpdateView(NULL, NULL);
|
|
}
|
|
|
|
CView* CSelector::GetCurrentView()
|
|
{
|
|
return m_pCurView;
|
|
}
|
|
|
|
CSelectorButton* CSelector::GetCurrentButton()
|
|
{
|
|
return m_pCurButton;
|
|
}
|
|
|
|
void CSelector::OnSize( UINT nType, int cx, int cy )
|
|
{
|
|
if (cy > m_boundingBox.Height() && m_scrollPos > 0)
|
|
{ // resize bigger need to scroll down.
|
|
ScrollWindowEx( 0, SCROLLSTEP, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE);
|
|
m_scrollPos -= SCROLLSTEP;
|
|
|
|
}
|
|
int32 dockStyle = ((CNSNavFrame*)GetParent())->GetDockStyle();
|
|
if (dockStyle == DOCKSTYLE_HORZTOP || dockStyle == DOCKSTYLE_HORZBOTTOM)
|
|
{
|
|
int left = cx-m_hScrollBmpSize.cx;
|
|
m_scrollUp->MoveWindow(0, 0, m_hScrollBmpSize.cx, m_hScrollBmpSize.cy);
|
|
m_scrollUp->setBoundingBox(0, 0, m_hScrollBmpSize.cx, m_hScrollBmpSize.cy);
|
|
m_scrollDown->MoveWindow(left, 0, m_hScrollBmpSize.cx , m_hScrollBmpSize.cy);
|
|
m_scrollDown->setBoundingBox(left, 0, left + m_hScrollBmpSize.cx, m_hScrollBmpSize.cy);
|
|
}
|
|
else
|
|
{
|
|
int top = cy - m_hScrollBmpSize.cy;
|
|
int left = cx-m_hScrollBmpSize.cx;
|
|
m_scrollUp->MoveWindow(left, 0, m_hScrollBmpSize.cx, m_hScrollBmpSize.cy);
|
|
m_scrollUp->setBoundingBox(left, 0, left + m_hScrollBmpSize.cx , m_hScrollBmpSize.cy);
|
|
m_scrollDown->MoveWindow(left, top, m_hScrollBmpSize.cx , m_hScrollBmpSize.cy);
|
|
m_scrollDown->setBoundingBox(left, top, left + m_hScrollBmpSize.cx, top + m_hScrollBmpSize.cy);
|
|
}
|
|
ShowScrollButton(NULL);
|
|
GetClientRect(&m_boundingBox);
|
|
RearrangeIcons();
|
|
}
|
|
|
|
|
|
|
|
void CSelector::ShowScrollButton(CSelectorButton* button)
|
|
{
|
|
CRect tempRect;
|
|
CNSNavFrame* pParent = (CNSNavFrame*)GetParent();
|
|
int32 dockstyle = pParent->GetDockStyle();
|
|
GetClientRect(&tempRect);
|
|
// checked if we need to display the scroll button
|
|
if (dockstyle == DOCKSTYLE_FLOATING || dockstyle == DOCKSTYLE_VERTLEFT ||
|
|
dockstyle == DOCKSTYLE_VERTRIGHT) {
|
|
if ((m_ypos - m_hScrollBmpSize.cy) > (tempRect.Height() - ICONYPOS)) {
|
|
m_scrollUp->ShowWindow(SW_SHOW);
|
|
m_scrollDown->ShowWindow(SW_SHOW);
|
|
m_scrollUp->Invalidate();
|
|
m_scrollDown->Invalidate();
|
|
}
|
|
else {
|
|
m_scrollUp->ShowWindow(SW_HIDE);
|
|
m_scrollDown->ShowWindow(SW_HIDE);
|
|
}
|
|
}
|
|
else {
|
|
if ((m_xpos - m_hScrollBmpSize.cx) > (tempRect.Width() - ICONXPOS)) {
|
|
m_scrollUp->ShowWindow(SW_SHOW);
|
|
m_scrollDown->ShowWindow(SW_SHOW);
|
|
m_scrollUp->Invalidate();
|
|
m_scrollDown->Invalidate();
|
|
}
|
|
else {
|
|
m_scrollUp->ShowWindow(SW_HIDE);
|
|
m_scrollDown->ShowWindow(SW_HIDE);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CSelector::AddViewContext(const char* pTitle, CView* pView, CRDFContentView* pTree,
|
|
CPaneCX* htmlPane, HT_View theView)
|
|
{
|
|
CSelectorButton* theNSViewButton = new CSelectorButton(this);
|
|
|
|
// Button meets the view. View meets the button.
|
|
theNSViewButton->SetHTView(theView);
|
|
theNSViewButton->SetTreeView(pTree);
|
|
|
|
HT_SetViewFEData(theView, theNSViewButton);
|
|
|
|
HT_Resource node = theView ? HT_TopNode(theView) : NULL;
|
|
char* pNodeURL = node ? HT_GetNodeURL(node) : "";
|
|
|
|
theNSViewButton->Create(this, theApp.m_pToolbarStyle, CSize(60,42), CSize(85, 25),
|
|
pTitle,
|
|
pTitle, pNodeURL,
|
|
CSize(23,23), 10, 5,
|
|
node,
|
|
TB_HAS_DRAGABLE_MENU | TB_HAS_TIMED_MENU, pView, htmlPane);
|
|
|
|
CRect rect;
|
|
rect.left = (long)m_xpos;
|
|
rect.top = (long)m_ypos;
|
|
|
|
CSize buttonSize = theNSViewButton->GetRequiredButtonSize();
|
|
rect.right = rect.left + buttonSize.cx;
|
|
rect.bottom = rect.top + buttonSize.cy;
|
|
|
|
CNSNavFrame* pFrame = (CNSNavFrame*)GetParentFrame();
|
|
int32 dockStyle = pFrame->GetDockStyle();
|
|
|
|
if (dockStyle == DOCKSTYLE_HORZTOP || dockStyle == DOCKSTYLE_HORZBOTTOM)
|
|
{
|
|
m_xpos += BUTTON_WIDTH + 2;
|
|
rect.bottom = rect.top + BUTTON_HEIGHT;
|
|
}
|
|
else
|
|
{
|
|
m_ypos += buttonSize.cy + 2;
|
|
rect.right = rect.left + BUTTON_WIDTH;
|
|
}
|
|
/*
|
|
CString originalText = HT_GetNodeName(theNSViewButton->GetNode());
|
|
int currCount = originalText.GetLength();
|
|
|
|
// Start off at the maximal string
|
|
CString strTxt = originalText;
|
|
|
|
CSize theSize = theNSViewButton->GetButtonSizeFromChars(originalText, currCount);
|
|
int horExtent = theSize.cx;
|
|
|
|
while (horExtent > BUTTON_WIDTH)
|
|
{
|
|
strTxt = originalText.Left(currCount-3) + "...";
|
|
theSize = theNSViewButton->GetButtonSizeFromChars(strTxt, currCount);
|
|
horExtent = theSize.cx;
|
|
currCount--;
|
|
}
|
|
|
|
theNSViewButton->SetTextWithoutResize(strTxt);
|
|
*/
|
|
|
|
ShowScrollButton(theNSViewButton);
|
|
}
|
|
|
|
|
|
void CSelector::PopulatePane()
|
|
{
|
|
// Construct the notification struct used by HT
|
|
HT_Notification ns = new HT_NotificationStruct;
|
|
ns->notifyProc = notifyProcedure;
|
|
ns->data = this;
|
|
m_Notification = ns;
|
|
|
|
// Construct the pane and give it our notification struct
|
|
m_Pane = HT_NewPane(ns);
|
|
HT_SetPaneFEData(m_Pane, this);
|
|
|
|
// Inform our XP layer of the new nav center.
|
|
MWContext *pDockedCX = NULL;
|
|
CNSNavFrame *pParentFrame = GetParentFrame()->IsKindOf(RUNTIME_CLASS(CNSNavFrame)) ? (CNSNavFrame*)GetParentFrame() : NULL;
|
|
// Since the XP layer isn't set up yet, we can't use
|
|
// XP_IsNavCenterDocked in order to tell
|
|
// if the window is docked. Use instead wether or
|
|
// not the frame has a parent.
|
|
if(pParentFrame && pParentFrame->GetParent()) {
|
|
CFrameGlue *pGlue = CFrameGlue::GetFrameGlue(pParentFrame->GetTopLevelFrame());
|
|
if(pGlue && pGlue->GetMainContext()) {
|
|
pDockedCX = pGlue->GetMainContext()->GetContext();
|
|
}
|
|
ASSERT(pDockedCX);
|
|
}
|
|
XP_RegisterNavCenter(m_Pane, pDockedCX);
|
|
|
|
// Place any icons that were immediately available. (The remote ones will trickle in later, and we'll
|
|
// rearrange the selector bar when we get those VIEW_ADDED events.)
|
|
RearrangeIcons();
|
|
}
|
|
|
|
void CSelector::ConstructView(HT_View theView)
|
|
{
|
|
if (theView == NULL)
|
|
return;
|
|
|
|
CString viewName = HT_GetNodeName(HT_TopNode(theView));
|
|
|
|
// Construct the RDF view
|
|
CWnd *theParent = (CWnd *)(((CNSNavFrame*)GetParentFrame())->GetContentView());
|
|
|
|
DWORD dwCurrentStyle = WS_CHILD;
|
|
|
|
// Parent may change depending on view (need more panes).
|
|
CRect rClient(0, 0, 100, 100);
|
|
CContentView *pAltParent = NULL;
|
|
CPaneCX *pCX = NULL;
|
|
if(HT_HasHTMLPane(theView))
|
|
{
|
|
pAltParent = new CContentView();
|
|
pAltParent->Create(NULL, "", WS_CHILD, rClient, theParent, NC_IDW_MISCVIEW, NULL);
|
|
pCX = wfe_CreateNavCenterHTMLPain(theView, pAltParent->m_hWnd);
|
|
|
|
// Make all other children visible now (we control visibility by being the parent).
|
|
dwCurrentStyle |= WS_VISIBLE;
|
|
}
|
|
if(pAltParent) {
|
|
theParent = (CWnd *)pAltParent;
|
|
}
|
|
theParent->GetClientRect(&rClient);
|
|
|
|
// Can't use CSelector's m_Pane, because it might not have been initialized yet. Calls
|
|
// HT_GetPane instead.
|
|
CRDFOutlinerParent* newParent = new CRDFOutlinerParent(HT_GetPane(theView), theView);
|
|
CRDFContentView* newView = new CRDFContentView(newParent);
|
|
|
|
// Create the windows
|
|
newView->Create( NULL, "", dwCurrentStyle, rClient, theParent, NC_IDW_OUTLINER);
|
|
|
|
// Initialize the columns, etc.
|
|
newParent->Initialize();
|
|
|
|
// Name and icon for the view correspond to the name/icon of the top node in the view.
|
|
AddViewContext(viewName, pAltParent ? (CView *)pAltParent : (CView *)newView, newView, pCX, theView);
|
|
}
|
|
|
|
void CSelector::DestroyViews()
|
|
{
|
|
int viewCount = HT_GetViewListCount(m_Pane);
|
|
for (int i = 0; i < viewCount; i++)
|
|
{
|
|
HT_View v = HT_GetNthView(m_Pane, i);
|
|
if (v != NULL)
|
|
{
|
|
CRDFContentView* theView = (CRDFContentView*)(HT_GetViewFEData(v));
|
|
delete theView;
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CSelector::OnEraseBkgnd( CDC* pDC )
|
|
{
|
|
int i = 0;
|
|
return CWnd::OnEraseBkgnd(pDC);
|
|
}
|
|
|
|
|
|
void CSelector::ScrollSelector()
|
|
{
|
|
if (m_scrollDirection == SCROLLUP || m_scrollDirection == SCROLLLEFT) {
|
|
if (m_scrollPos > 0) {
|
|
if (m_scrollDirection == SCROLLUP)
|
|
ScrollWindowEx( 0, SCROLLSTEP, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE);
|
|
else
|
|
ScrollWindowEx( SCROLLSTEP, 0, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE);
|
|
m_scrollPos -= SCROLLSTEP;
|
|
}
|
|
}
|
|
else {
|
|
RECT rect;
|
|
GetClientRect(&rect);
|
|
if (m_scrollDirection == SCROLLDOWN) {
|
|
if (m_scrollPos + (rect.bottom - rect.top) < m_ypos) {
|
|
ScrollWindowEx( 0, -SCROLLSTEP, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE);
|
|
m_scrollPos += SCROLLSTEP;
|
|
}
|
|
else if (m_scrollPos + (rect.right - rect.left) < m_xpos) {
|
|
ScrollWindowEx( -SCROLLSTEP, 0, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE);
|
|
m_scrollPos += SCROLLSTEP;
|
|
}
|
|
}
|
|
}
|
|
ShowScrollButton(NULL);
|
|
m_scrollUp->AdjustPos();
|
|
m_scrollDown->AdjustPos();
|
|
}
|
|
|
|
|
|
void CSelector::OnParentNotify( UINT message, LPARAM lParam )
|
|
{
|
|
if (message == WM_LBUTTONDOWN) {
|
|
POINT pt;
|
|
pt.x = LOWORD(lParam); // horizontal position of cursor
|
|
pt.y = HIWORD(lParam); // vertical position of cursor
|
|
CNSNavFrame* pParent = (CNSNavFrame*)GetParent();
|
|
int32 dockStyle = pParent->GetDockStyle();
|
|
if (m_scrollUp->IsPtInRect(pt)) {
|
|
if (dockStyle == DOCKSTYLE_HORZTOP)
|
|
m_scrollDirection = SCROLLLEFT;
|
|
else
|
|
m_scrollDirection = SCROLLUP;
|
|
}
|
|
else if (m_scrollDown->IsPtInRect(pt)){ // scroll down.
|
|
if (dockStyle == DOCKSTYLE_HORZBOTTOM)
|
|
m_scrollDirection = SCROLLRIGHT;
|
|
else
|
|
m_scrollDirection = SCROLLDOWN;
|
|
}
|
|
ScrollSelector();
|
|
}
|
|
CWnd::OnParentNotify( message, lParam );
|
|
}
|
|
|
|
void CSelector::RearrangeIcons()
|
|
{
|
|
if (m_Pane == NULL)
|
|
return;
|
|
|
|
CNSNavFrame* pFrame = (CNSNavFrame*)GetParentFrame();
|
|
int32 dockStyle = pFrame->GetDockStyle();
|
|
|
|
CRect tempRect;
|
|
if (dockStyle == DOCKSTYLE_HORZTOP || dockStyle == DOCKSTYLE_HORZBOTTOM)
|
|
{
|
|
m_xpos = ICONXPOS;
|
|
m_ypos = 2;
|
|
}
|
|
else {
|
|
m_xpos = 2;
|
|
m_ypos = ICONYPOS;
|
|
}
|
|
CRect parentRect;
|
|
CSelectorButton* theButton = NULL;
|
|
GetClientRect(&parentRect);
|
|
|
|
int count = HT_GetViewListCount(m_Pane);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
HT_View view = HT_GetNthView(m_Pane, i);
|
|
|
|
if (view && HT_GetViewFEData(view))
|
|
{
|
|
theButton = (CSelectorButton*)HT_GetViewFEData(view);
|
|
|
|
CSize buttonSize = theButton->GetRequiredButtonSize();
|
|
|
|
if (dockStyle == DOCKSTYLE_FLOATING || dockStyle == DOCKSTYLE_VERTLEFT ||
|
|
dockStyle == DOCKSTYLE_VERTRIGHT)
|
|
{ // draw icon from top to bottom
|
|
theButton->MoveWindow((int)m_xpos, (int)m_ypos,
|
|
BUTTON_WIDTH, buttonSize.cy, TRUE);
|
|
|
|
m_ypos += buttonSize.cy + 2;
|
|
}
|
|
else
|
|
{ // draw icon from left to right.
|
|
theButton->MoveWindow((int)m_xpos, (int)m_ypos,
|
|
BUTTON_WIDTH, buttonSize.cy, TRUE);
|
|
m_xpos += BUTTON_WIDTH + 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CSelectorButton* CSelector::GetButtonFromPoint(CPoint point, int& dragFraction)
|
|
{
|
|
CRect buttonRect;
|
|
|
|
CNSNavFrame* pFrame = (CNSNavFrame*)GetParentFrame();
|
|
int32 dockStyle = pFrame->GetDockStyle();
|
|
|
|
CSelectorButton* pButton = NULL;
|
|
int count = HT_GetViewListCount(m_Pane);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
HT_View view = HT_GetNthView(m_Pane, i);
|
|
|
|
if (view && HT_GetViewFEData(view))
|
|
{
|
|
pButton = (CSelectorButton*)HT_GetViewFEData(view);
|
|
pButton->GetClientRect(&buttonRect);
|
|
pButton->MapWindowPoints(this, &buttonRect);
|
|
|
|
if (buttonRect.PtInRect(point))
|
|
{
|
|
int hitY = point.y;
|
|
if (point.y >= buttonRect.top && point.y <= buttonRect.top + buttonRect.Height()/4.0)
|
|
dragFraction = 1;
|
|
else if (point.y >= buttonRect.bottom - buttonRect.Height()/4.0)
|
|
dragFraction = 3;
|
|
else dragFraction = 2;
|
|
|
|
return pButton;
|
|
}
|
|
|
|
if (dockStyle == DOCKSTYLE_FLOATING || dockStyle == DOCKSTYLE_VERTLEFT ||
|
|
dockStyle == DOCKSTYLE_VERTRIGHT)
|
|
{
|
|
if (point.y <= buttonRect.bottom)
|
|
{
|
|
dragFraction = 1;
|
|
return pButton;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (point.x <= buttonRect.right)
|
|
{
|
|
dragFraction = 1;
|
|
return pButton;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dragFraction = 3;
|
|
return pButton;
|
|
}
|
|
|
|
void CSelector::OnTimer(UINT nID)
|
|
{
|
|
CWnd::OnTimer(nID);
|
|
if (nID == IDT_PANESWITCH)
|
|
{
|
|
if (m_hPaneSwitchTimer != 0)
|
|
{
|
|
KillSwitchTimer();
|
|
}
|
|
|
|
// Do the pane switch
|
|
if (m_pCurButton != GetDragButton())
|
|
{
|
|
// There's actually something that needs to be done.
|
|
if (m_pCurButton) // Something is depressed
|
|
GetDragButton()->OnAction();
|
|
else // Nothing is depressed. Use popup menus instead.
|
|
GetDragButton()->DisplayMenuOnDrag();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CSelector::OnLButtonDown (UINT nFlags, CPoint point )
|
|
{
|
|
// Called when the user clicks on the menu bar. Start a drag or collapse the view.
|
|
if (m_pCurButton)
|
|
{
|
|
CRDFContentView* pView = m_pCurButton->GetTreeView();
|
|
if (pView)
|
|
pView->SetFocus();
|
|
}
|
|
|
|
m_PointHit = point;
|
|
SetCapture();
|
|
}
|
|
|
|
|
|
void CSelector::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
if (GetCapture() == this)
|
|
{
|
|
CNSNavFrame* navFrameParent = (CNSNavFrame*)GetParentFrame();
|
|
|
|
if (abs(point.x - m_PointHit.x) > 3 ||
|
|
abs(point.y - m_PointHit.y) > 3)
|
|
{
|
|
ReleaseCapture();
|
|
|
|
// Start a drag
|
|
MapWindowPoints(navFrameParent, &point, 1);
|
|
navFrameParent->StartDrag(point);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CSelector::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
if (GetCapture() == this)
|
|
{
|
|
ReleaseCapture();
|
|
}
|
|
}
|
|
|
|
void CSelector::OnRButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
m_MenuCommandMap.Clear();
|
|
HT_Cursor theCursor = HT_NewContextualMenuCursor(NULL, PR_TRUE, PR_TRUE);
|
|
CMenu menu;
|
|
ClientToScreen(&point);
|
|
if (menu.CreatePopupMenu() != 0 && theCursor != NULL)
|
|
{
|
|
// We have a cursor. Attempt to iterate
|
|
HT_MenuCmd theCommand;
|
|
while (HT_NextContextMenuItem(theCursor, &theCommand))
|
|
{
|
|
char* menuName = HT_GetMenuCmdName(theCommand);
|
|
if (theCommand == HT_CMD_SEPARATOR)
|
|
menu.AppendMenu(MF_SEPARATOR);
|
|
else
|
|
{
|
|
// Add the command to our command map
|
|
CRDFMenuCommand* rdfCommand = new CRDFMenuCommand(menuName, theCommand);
|
|
int index = m_MenuCommandMap.AddCommand(rdfCommand);
|
|
menu.AppendMenu(MF_ENABLED, index+FIRST_HT_MENU_ID, menuName);
|
|
}
|
|
}
|
|
HT_DeleteCursor(theCursor);
|
|
|
|
menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this, NULL);
|
|
|
|
menu.DestroyMenu();
|
|
}
|
|
}
|
|
|
|
BOOL CSelector::OnCommand( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
if (wParam >= FIRST_HT_MENU_ID && wParam <= LAST_HT_MENU_ID)
|
|
{
|
|
// A selection was made from the context menu.
|
|
// Use the menu map to get the HT command value
|
|
CRDFMenuCommand* theCommand = (CRDFMenuCommand*)(m_MenuCommandMap.GetCommand((int)wParam-FIRST_HT_MENU_ID));
|
|
if (theCommand)
|
|
{
|
|
HT_MenuCmd htCommand = theCommand->GetHTCommand();
|
|
HT_DoMenuCmd(m_Pane, htCommand);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
CSelectorDropTarget::CSelectorDropTarget(CSelector* pParent)
|
|
{
|
|
fd = 0;
|
|
m_pParent = pParent;
|
|
}
|
|
|
|
CSelectorDropTarget::~CSelectorDropTarget()
|
|
{
|
|
delete fd;
|
|
}
|
|
|
|
|
|
BOOL CSelectorDropTarget::OnDrop(CWnd* pWnd,
|
|
COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
|
|
{
|
|
CSelector* pSelector = (CSelector*)pWnd;
|
|
HT_View theView = pSelector->GetDragButton()->GetHTView();
|
|
pSelector->SetDragButton(NULL);
|
|
if (pSelector->GetSwitchTimer() != 0)
|
|
pSelector->KillSwitchTimer();
|
|
if (theView)
|
|
{
|
|
// Do a drop.
|
|
RDFGLOBAL_PerformDrop(pDataObject, HT_TopNode(theView), pSelector->GetDragFraction());
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
if(!pDataObject || !pWnd)
|
|
return(FALSE);
|
|
|
|
#ifdef XP_WIN32
|
|
// we only handle text at the moment
|
|
if(! (pDataObject->IsDataAvailable(CF_TEXT) || pDataObject->IsDataAvailable(CF_UNICODETEXT)))
|
|
return(FALSE);
|
|
#else
|
|
// we only handle text at the moment
|
|
if(!pDataObject->IsDataAvailable(CF_TEXT))
|
|
return(FALSE);
|
|
#endif
|
|
|
|
CSelector * cView = (CSelector *) pWnd;
|
|
|
|
BOOL bUseUnicodeData = FALSE;
|
|
|
|
// get the data
|
|
HGLOBAL hString = pDataObject->GetGlobalData(CF_TEXT);
|
|
if(hString == NULL)
|
|
return(FALSE);
|
|
|
|
// get a pointer to the actual bytes
|
|
char * pString = (char *) GlobalLock(hString);
|
|
if(!pString)
|
|
return(FALSE);
|
|
|
|
m_url = pString;
|
|
|
|
GlobalUnlock(hString);
|
|
if (strnicmp(m_url, "mailto:", 7) == 0) { // drag from mail and new
|
|
|
|
// Generic brain dead interface to GetUrl.
|
|
pSaveContext = new CSaveCX(NULL, "MCF Viewer", pWnd);
|
|
// Create the stream which will do the actual work.
|
|
#ifndef XP_WIN16
|
|
pSaveContext->Create(CSaveCX::IDD, m_pParent);
|
|
#elif defined(DEBUG_hyatt) || defined(DEBUG_mhwang) || defined(DEBUG_rjc) || defined(DEBUG_guha)
|
|
// TODO -WIND16 Fix the saving of MCF correctly, and stop using static strings
|
|
#endif
|
|
fd = 0;
|
|
NET_StreamClass *pStream = NET_NewStream("Saving MCF file",
|
|
MCFSaveWrite,
|
|
MCFSaveComplete,
|
|
MCFSaveAbort,
|
|
MCFSaveReady,
|
|
this,
|
|
pSaveContext->GetContext());
|
|
|
|
pSaveContext->SetSecondaryStream(pStream);
|
|
// Load it.
|
|
URL_Struct *pUrlStruct = NET_CreateURLStruct(m_url, NET_DONT_RELOAD);
|
|
pSaveContext->GetUrl(pUrlStruct, FO_CACHE_AND_SAVE_AS, TRUE, FALSE);
|
|
}
|
|
else
|
|
{
|
|
CWnd* pWindowHit = m_pParent->ChildWindowFromPoint( point );
|
|
if (pWindowHit)
|
|
{
|
|
CSelectorButton* theButton = (CSelectorButton*)pWindowHit;
|
|
CPoint point(-1, -1);
|
|
return theButton->GetView()->OnDrop(pDataObject, dropEffect, point);
|
|
}
|
|
else
|
|
{ // create a new work space.
|
|
HT_NewWorkspace(m_url.GetBuffer(m_url.GetLength()), m_pParent, m_pParent->GetHTPane());
|
|
}
|
|
}
|
|
*/
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
LRESULT CSelector::OnButtonDrag(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HWND hWnd = (HWND) lParam;
|
|
|
|
CWnd *pButton = CWnd::FromHandle(hWnd);
|
|
|
|
COleDataSource * pDataSource = new COleDataSource;
|
|
CSelectorButton* pSelButton = (CSelectorButton*)pButton;
|
|
|
|
pSelButton->FillInOleDataSource(pDataSource);
|
|
|
|
// Need to clear the selection, since I use that for dropping stuff.
|
|
HT_SetSelection(HT_TopNode(pSelButton->GetHTView()));
|
|
|
|
// Don't start drag until outside this rect
|
|
RECT rectDragStart;
|
|
pButton->GetClientRect(&rectDragStart);
|
|
pButton->MapWindowPoints(this, &rectDragStart);
|
|
|
|
DROPEFFECT effect;
|
|
CToolbarDropSource * pDropSource = new CToolbarDropSource;
|
|
|
|
effect=pDataSource->DoDragDrop(DROPEFFECT_COPY | DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_SCROLL | DROPEFFECT_NONE,
|
|
&rectDragStart, pDropSource);
|
|
|
|
delete pDropSource;
|
|
delete pDataSource;
|
|
|
|
return 1;
|
|
}
|
|
|
|
DROPEFFECT CSelectorDropTarget::OnDragEnter(CWnd* pWnd,
|
|
COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
|
|
{
|
|
return OnDragOver(pWnd, pDataObject, dwKeyState, point);
|
|
}
|
|
|
|
DROPEFFECT CSelectorDropTarget::OnDragOver(CWnd* pWnd,
|
|
COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
|
|
{
|
|
CSelector* pSelector = (CSelector*)pWnd;
|
|
int dragFraction;
|
|
|
|
CSelectorButton* pButton = pSelector->GetButtonFromPoint(point, dragFraction);
|
|
HT_Resource theNode = pButton ? pButton->GetNode() : NULL;
|
|
|
|
// Give some drag feedback.
|
|
DROPEFFECT answer = RDFGLOBAL_TranslateDropAction(theNode, pDataObject, dragFraction);
|
|
|
|
if (pButton != pSelector->GetDragButton() || dragFraction != pSelector->GetDragFraction())
|
|
{
|
|
// User is over a different button or different part of the same button
|
|
if (pSelector->GetSwitchTimer() != 0)
|
|
pSelector->KillSwitchTimer(); // Kill the existing pane switch timer.
|
|
|
|
pSelector->SetDragButton(pButton);
|
|
pSelector->SetDragFraction(dragFraction);
|
|
|
|
if (answer != DROPEFFECT_NONE && dragFraction == 2) // Set the pane switching timer if the user can drop here.
|
|
pSelector->SetSwitchTimer();
|
|
else
|
|
{
|
|
// Kill any menus that are up.
|
|
CDropMenu* theLastMenu = CDropMenu::GetLastDropMenu();
|
|
if(theLastMenu !=NULL)
|
|
{
|
|
//we only want one drop menu open at a time, so close the last one if one is
|
|
//still open.
|
|
theLastMenu->Deactivate();
|
|
CDropMenu::SetLastDropMenu(NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
return answer;
|
|
}
|
|
|
|
void CSelectorDropTarget::OnDragLeave(CWnd* pWnd)
|
|
{
|
|
CSelector* pSelector = (CSelector*)pWnd;
|
|
pSelector->SetDragButton(NULL);
|
|
if (pSelector->GetSwitchTimer() != 0)
|
|
{
|
|
pSelector->KillSwitchTimer();
|
|
}
|
|
}
|
|
|
|
|
|
IMPLEMENT_DYNAMIC(CNavSelScrollButton, CButton)
|
|
BEGIN_MESSAGE_MAP(CNavSelScrollButton, CButton)
|
|
//{{AFX_MSG_MAP(CMainFrame)
|
|
// ON_WM_LBUTTONUP()
|
|
// NOTE - the ClassWizard will add and remove mapping macros here.
|
|
// DO NOT EDIT what you see in these blocks of generated code !
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
CNavSelScrollButton::CNavSelScrollButton(HBITMAP hBmp, int width, int index, int height)
|
|
{
|
|
m_hbmp = hBmp;
|
|
m_width = width;
|
|
m_index = index;
|
|
m_height = height;
|
|
m_selected = FALSE;
|
|
}
|
|
|
|
void CNavSelScrollButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
|
|
{
|
|
if (lpDrawItemStruct->itemAction == ODA_FOCUS )
|
|
return;
|
|
if ( m_hbmp ) {
|
|
RECT rect;
|
|
GetClientRect(&rect);
|
|
int index = m_index; // normal state bitmap.
|
|
HDC hdcBitmap = ::CreateCompatibleDC( lpDrawItemStruct->hDC );
|
|
|
|
HBITMAP hbmOld = (HBITMAP) ::SelectObject( hdcBitmap, m_hbmp );
|
|
|
|
if ((lpDrawItemStruct->itemAction == ODA_SELECT) &&
|
|
((lpDrawItemStruct->itemState & ODS_SELECTED) == ODS_SELECTED)) {
|
|
if (m_selected) {
|
|
m_selected = FALSE;
|
|
}
|
|
else {
|
|
m_selected = TRUE;
|
|
index = m_index + 1; // selected state bitmap.
|
|
}
|
|
}
|
|
FEU_TransBlt( lpDrawItemStruct->hDC,
|
|
lpDrawItemStruct->rcItem.right - m_width,
|
|
lpDrawItemStruct->rcItem.top,
|
|
m_width, m_height,
|
|
hdcBitmap,
|
|
index * m_width, 0 ,WFE_GetUIPalette(GetParentFrame())
|
|
);
|
|
|
|
::SelectObject( hdcBitmap, hbmOld );
|
|
ShowWindow(SW_SHOW);
|
|
VERIFY( ::DeleteDC( hdcBitmap ));
|
|
CRgn pRgn;
|
|
pRgn.CreateRectRgn( m_boundBox.left, m_boundBox.top,
|
|
m_boundBox.right, m_boundBox.bottom );
|
|
GetParent()->ValidateRgn( &pRgn );
|
|
pRgn.DeleteObject();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int MCFSaveReady(NET_StreamClass *stream)
|
|
{
|
|
// Get our save context out of the data object.
|
|
CSelectorDropTarget* pDropTarget = (CSelectorDropTarget*)stream->data_object;
|
|
if (!pDropTarget->fd) {
|
|
strcpy(pDropTarget->fileName, WH_TempFileName(xpTemporary, "mcf", ".mcf"));
|
|
pDropTarget->fd = new CFile(pDropTarget->fileName, CFile::modeCreate | CFile::modeWrite );
|
|
}
|
|
return (MAX_WRITE_READY);
|
|
}
|
|
|
|
int MCFSaveWrite(NET_StreamClass *stream, const char *pWriteData, int32 iDataLength)
|
|
{
|
|
CSelectorDropTarget* pDropTarget = (CSelectorDropTarget*)stream->data_object;
|
|
if (!pDropTarget->fd) {
|
|
strcpy(pDropTarget->fileName, WH_TempFileName(xpTemporary, "mcf", ".mcf"));
|
|
pDropTarget->fd = new CFile(pDropTarget->fileName, CFile::modeCreate | CFile::modeWrite );
|
|
}
|
|
pDropTarget->fd->Write( pWriteData, (UINT)iDataLength );
|
|
|
|
// Return the amount written, or error.
|
|
return((UINT)iDataLength);
|
|
}
|
|
|
|
void MCFSaveComplete(NET_StreamClass *stream)
|
|
{
|
|
CSelectorDropTarget* pDropTarget = (CSelectorDropTarget*)stream->data_object;
|
|
pDropTarget->fd->Close( );
|
|
/*
|
|
HT_NewWorkspace(pDropTarget->fileName, pDropTarget->m_pParent, pDropTarget->m_pParent->GetHTPane());
|
|
*/
|
|
}
|
|
void MCFSaveAbort(NET_StreamClass *stream, int iStatus)
|
|
{
|
|
}
|
|
|