home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / navcntr.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  34.5 KB  |  1,251 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "stdafx.h"
  20. #include "navfram.h"
  21. #include "feimage.h"
  22. #include "net.h"
  23. #include "cxsave.h"
  24. #include "cxicon.h"
  25. #include "fegui.h"
  26. #include "rdfliner.h"
  27. #include "mmsystem.h"
  28. #include "winproto.h"
  29. #include "xp_ncent.h"
  30. #include "pain.h"
  31.  
  32. #ifdef _DEBUG
  33. #define new DEBUG_NEW
  34. #undef THIS_FILE
  35. static char THIS_FILE[] = __FILE__;
  36. #endif
  37. #ifndef _AFXDLL
  38. #undef new
  39. #endif
  40.  
  41. #ifndef _AFXDLL
  42. #define new DEBUG_NEW
  43. #endif
  44.  
  45. #include "dropmenu.h"
  46.  
  47. //////////////////////////
  48. // RDF Event Handlers
  49.  
  50. // The Main Event Handler for the NavCenter.  Handles events on the selector bar AND within the tree
  51. // views.
  52. void notifyProcedure (HT_Notification ns, HT_Resource n, HT_Event whatHappened) 
  53. {
  54.     CSelector* theSelector = (CSelector*)ns->data;
  55.     if (theSelector == NULL)
  56.         return;
  57.  
  58.     HT_View theView = HT_GetView(n);
  59.     
  60.     // The pane has to handle some events.  These will go here.
  61.     if (whatHappened == HT_EVENT_VIEW_SELECTED)
  62.     {
  63.         CView* pView = theSelector->GetCurrentView();
  64.         CSelectorButton* pButton = theSelector->GetCurrentButton();
  65.  
  66.         // If the new selected view is NULL, then we need to make sure our pane is closed.
  67.         if (theView == NULL && pView != NULL)
  68.         {
  69.             // We're open.  Close the pane.
  70.             ((CNSNavFrame*)theSelector->GetParentFrame())->CollapseWindow();
  71.         }
  72.         else if (theView != NULL)
  73.         {
  74.             // We have a view. Select it.
  75.             CSelectorButton* pButton = (CSelectorButton*)HT_GetViewFEData(theView);
  76.             theSelector->SetCurrentView(pButton);
  77.  
  78.             if (pView == NULL)
  79.             {
  80.                 // Need to open the pane.
  81.                 ((CNSNavFrame*)theSelector->GetParentFrame())->ExpandWindow();
  82.             }
  83.         }
  84.         return;
  85.     }
  86.     
  87.     if (theView == NULL)
  88.         return;
  89.  
  90.     if (whatHappened == HT_EVENT_VIEW_ADDED) 
  91.     {
  92.         theSelector->ConstructView(theView);
  93.         theSelector->RearrangeIcons();
  94.         CSelectorButton* pButton = (CSelectorButton*)HT_GetViewFEData(theView);
  95.     }
  96.     else if (whatHappened == HT_EVENT_VIEW_DELETED)
  97.     {
  98.         // Delete the content view
  99.         CSelectorButton* pButton = (CSelectorButton*)HT_GetViewFEData(theView);
  100.         pButton->GetView()->DestroyWindow();
  101.  
  102.         // Delete the button
  103.         delete pButton;
  104.  
  105.         // Remove our FE data
  106.         HT_SetViewFEData(theView, NULL);
  107.     }
  108.     else if (whatHappened == HT_EVENT_NODE_VPROP_CHANGED && HT_TopNode(theView) == n)
  109.     {
  110.         // Top level node changed its name.  Need to change the button text, window title bar, and 
  111.         // embedded nav menu bar.
  112.     }
  113.     else if (whatHappened == HT_EVENT_NODE_EDIT && HT_TopNode(theView) == n)
  114.     {
  115.         // Edit being performed on a selector bar item. (STILL TO DO)
  116.     }
  117.     else if (whatHappened == HT_EVENT_VIEW_WORKSPACE_REFRESH)
  118.         theSelector->RearrangeIcons(); // Redraw the selector.
  119.  
  120.     // If the pane doesn't handle the event, then a view does.
  121.     else 
  122.     {
  123.         // View needs to exist in order for us to send this event to it.
  124.         CSelectorButton* pButton = (CSelectorButton*)HT_GetViewFEData(theView);
  125.         if (pButton)
  126.         {
  127.             CRDFContentView* theOutlinerView = (CRDFContentView*)pButton->GetTreeView();
  128.             if (theOutlinerView)
  129.             {
  130.                 CRDFOutliner* theOutliner = (CRDFOutliner*)(theOutlinerView->GetOutlinerParent()->GetOutliner());
  131.                 theOutliner->HandleEvent(ns, n, whatHappened);
  132.             }
  133.         }
  134.     }
  135. }
  136.  
  137. // The Event Handler for selector popup menus
  138. static void selectorPopupNotifyProcedure (HT_Notification ns, HT_Resource n, HT_Event whatHappened) 
  139. {
  140.     // We respond only to open/closed events.  This procedure is only entered when the user clicks
  141.     // and holds on a selector bar button to bring up a popup menu.
  142.   CSelectorButton* theButton = (CSelectorButton*)ns->data;
  143.   if (n != NULL)
  144.   {
  145.     HT_View theView = HT_GetView(n);
  146.     if (theView != NULL && (whatHappened == HT_EVENT_NODE_OPENCLOSE_CHANGED))
  147.     {
  148.       PRBool openState;
  149.       HT_GetOpenState(n, &openState);
  150.       if (openState)
  151.       {
  152.         theButton->FillInMenu(n);
  153.       }
  154.     }
  155.   }
  156. }
  157.  
  158. // SelectorButton
  159.  
  160. CSelectorButton::~CSelectorButton() 
  161. {
  162.     if (m_Pane)
  163.         HT_DeletePane(m_Pane);    
  164.     
  165.     m_Node = NULL;
  166. }
  167.  
  168. int CSelectorButton::Create(CWnd *pParent, int nToolbarStyle, CSize noviceButtonSize, 
  169.                             CSize advancedButtonSize,
  170.                             LPCTSTR pButtonText, LPCTSTR pToolTipText, 
  171.                             LPCTSTR pStatusText,
  172.                             CSize bitmapSize, int nMaxTextChars, int nMinTextChars, 
  173.                             HT_Resource pNode,
  174.                             DWORD dwButtonStyle, CView* view, CPaneCX* pane)
  175. {
  176.     pView = view;
  177.     m_pPane = pane;
  178.  
  179.     // Construct the notification struct used by HT
  180.     HT_Notification ns = new HT_NotificationStruct;
  181.     ns->notifyProc = selectorPopupNotifyProcedure;
  182.     ns->data = this;
  183.     
  184.     // Construct the pane and give it our notification struct
  185.     m_Pane = HT_PaneFromResource(HT_GetRDFResource(pNode), ns, (PRBool)TRUE);
  186.     HT_SetPaneFEData(m_Pane, this);
  187.  
  188.     HT_Resource pEntry = NULL;
  189.     HT_View theView = HT_GetSelectedView(m_Pane);
  190.     
  191.     BOOKMARKITEM bookmark; // For now, create with the pictures style. No text ever.
  192.     return CLinkToolbarButton::Create(pParent, TB_PICTURES, noviceButtonSize, advancedButtonSize,
  193.            pButtonText, pToolTipText, pStatusText, bitmapSize, nMaxTextChars, nMinTextChars,
  194.            bookmark, HT_TopNode(theView), dwButtonStyle);
  195. }
  196.  
  197. void CSelectorButton::OnAction()
  198. {
  199.     if (m_pDropMenu == NULL || !m_pDropMenu->IsOpen())
  200.     {
  201.         HT_Pane pane = HT_GetPane(m_HTView);
  202.         if (m_pSelector->GetCurrentButton() == this)
  203.         {
  204.             // View is already selected.  We are now closing the pane.
  205.             HT_SetSelectedView(pane, NULL);
  206.         }
  207.         else HT_SetSelectedView(pane, m_HTView);
  208.     }
  209. }
  210.  
  211. CSize CSelectorButton::GetButtonSizeFromChars(CString s, int c)
  212. {
  213.     if (m_nToolbarStyle == TB_PICTURES)
  214.         return GetBitmapOnlySize();
  215.     else if(m_nToolbarStyle == TB_TEXT)
  216.         return(GetTextOnlySize(s, c));
  217.     else
  218.         return(GetBitmapOnTopSize(s, c));
  219. }
  220.  
  221.  
  222. void CSelectorButton::DrawPicturesMode(HDC hDC, CRect rect)
  223. {
  224.  
  225.     DrawButtonBitmap(hDC, rect);
  226.  
  227. }
  228.  
  229. void CSelectorButton::DrawPicturesAndTextMode(HDC hDC, CRect rect)
  230. {
  231.     //DrawBitmapOnTop(hDC, rect);
  232.     DrawButtonBitmap(hDC, rect);
  233. }
  234.  
  235. void CSelectorButton::GetPicturesAndTextModeTextRect(CRect &rect)
  236. {
  237.     //GetBitmapOnTopTextRect(rect);
  238.     GetPicturesModeTextRect(rect);
  239. }
  240.  
  241. void CSelectorButton::GetPicturesModeTextRect(CRect &rect)
  242. {
  243.     //GetBitmapOnTopTextRect(rect);
  244.     CToolbarButton::GetPicturesModeTextRect(rect);
  245. }
  246.  
  247. void CSelectorButton::DisplayMenuOnDrag()
  248. {
  249.     CPoint point = RequestMenuPlacement();
  250.  
  251.     if(m_pDropMenu == NULL || !m_pDropMenu->IsOpen())
  252.     {
  253.         int nCount;
  254.         if(m_pDropMenu != NULL)
  255.         {
  256.             nCount = m_pDropMenu->GetMenuItemCount();
  257.  
  258.             // clean out the menu before adding to it
  259.             for(int i = nCount - 1; i >= 0; i--)
  260.             {
  261.                 m_pDropMenu->DeleteMenu(i, MF_BYPOSITION);
  262.             }
  263.             m_pDropMenu->DestroyDropMenu();
  264.             delete m_pDropMenu;
  265.         }
  266.  
  267.         m_pDropMenu = new CDropMenu;
  268.         SendMessage(NSDRAGMENUOPEN, (WPARAM)GetButtonCommand(), (LPARAM)m_pDropMenu);
  269.  
  270.         nCount = m_pDropMenu->GetMenuItemCount();
  271.  
  272.         if(nCount > 0)
  273.         {
  274.             CDropMenuDropTarget *dropTarget = new CDropMenuDropTarget(m_pDropMenu);
  275.             m_pDropMenu->TrackDropMenu(this, point.x, point.y, TRUE, dropTarget, TRUE);
  276.         }
  277.         else
  278.         {
  279.             CDropMenu* theLastMenu = CDropMenu::GetLastDropMenu();
  280.             if(theLastMenu !=NULL)
  281.             {
  282.                 //we only want one drop menu open at a time, so close the last one if one is
  283.                 //still open. 
  284.                 theLastMenu->Deactivate();
  285.                 CDropMenu::SetLastDropMenu(NULL);
  286.             }
  287.         }
  288.     }
  289. }
  290.  
  291. BOOL CSelectorButton::CreateRightMouseMenu()
  292. {
  293.     // Selector buttons should be selected if the tree is visible.
  294.     if (m_pSelector->IsTreeVisible())
  295.     {
  296.         // Actually switch to this view.
  297.         if (!m_bDepressed)
  298.         {
  299.             // Depress.
  300.             OnAction();
  301.         }
  302.     }
  303.  
  304.     // Build the actual menu.
  305.     m_MenuCommandMap.Clear();
  306.     
  307.     HT_Cursor theCursor = HT_NewContextualMenuCursor(m_HTView, PR_TRUE, PR_FALSE);
  308.     if (theCursor != NULL)
  309.     {
  310.         // We have a cursor. Attempt to iterate
  311.         HT_MenuCmd theCommand; 
  312.         while (HT_NextContextMenuItem(theCursor, &theCommand))
  313.         {
  314.             char* menuName = HT_GetMenuCmdName(theCommand);
  315.             if (theCommand == HT_CMD_SEPARATOR)
  316.                 m_menu.AppendMenu(MF_SEPARATOR);
  317.             else
  318.             {
  319.                 // Add the command to our command map
  320.                 CRDFMenuCommand* rdfCommand = new CRDFMenuCommand(menuName, theCommand);
  321.                 int index = m_MenuCommandMap.AddCommand(rdfCommand);
  322.                 m_menu.AppendMenu(MF_ENABLED, index+FIRST_HT_MENU_ID, menuName);
  323.             }
  324.         }
  325.         HT_DeleteCursor(theCursor);
  326.     }
  327.     return TRUE;
  328. }
  329. /////////////////////////////////////////////////////////////////////////////
  330. // CNavCenterFrame
  331.  
  332. //IMPLEMENT_DYNAMIC(CSelector, CScrollView)
  333. IMPLEMENT_DYNAMIC(CSelector, CView)
  334. BEGIN_MESSAGE_MAP(CSelector, CView)
  335.     //{{AFX_MSG_MAP(CMainFrame)
  336.         // NOTE - the ClassWizard will add and remove mapping macros here.
  337.         //    DO NOT EDIT what you see in these blocks of generated code !
  338.     ON_WM_CREATE()
  339.     ON_WM_SIZE()
  340.     ON_WM_MOUSEMOVE()
  341.     ON_WM_ERASEBKGND()
  342.     ON_WM_PARENTNOTIFY()
  343.     ON_WM_LBUTTONDOWN()
  344.     ON_WM_LBUTTONUP()
  345.     ON_WM_RBUTTONDOWN()
  346.     ON_WM_MOUSEMOVE()
  347.     ON_WM_TIMER()
  348.  
  349.     //}}AFX_MSG_MAP
  350. END_MESSAGE_MAP()
  351.  
  352. CSelector::CSelector()
  353. {
  354.     m_pCurView = NULL;
  355.     m_xpos =  ICONXPOS;
  356.     m_ypos = ICONYPOS;
  357.     m_pDropTarget = NULL;
  358.     m_Pane = NULL;
  359.     m_Notification = NULL;
  360.     m_scrollPos = 0;
  361.     m_pCurButton = NULL;
  362.     m_boundingBox.SetRectEmpty();
  363.     m_hScrollBmp = ::LoadBitmap( AfxGetResourceHandle(), 
  364.                                          MAKEINTRESOURCE( IDB_VFLIPPY ));
  365.     BITMAP bm;
  366.     ::GetObject( m_hScrollBmp, sizeof( bm ), &bm );
  367.     m_hScrollBmpSize.cx = bm.bmWidth / 4;
  368.     m_hScrollBmpSize.cy = bm.bmHeight;
  369.     m_scrollUp = new CNavSelScrollButton(m_hScrollBmp, m_hScrollBmpSize.cx, 0, m_hScrollBmpSize.cy);
  370.     m_scrollDown = new CNavSelScrollButton(m_hScrollBmp, m_hScrollBmpSize.cx, 2, m_hScrollBmpSize.cy);
  371.     m_scrollDirection = NOSCROLL;
  372.  
  373.     m_hPaneSwitchTimer = 0;
  374. }
  375.  
  376. CSelector::~CSelector()
  377. {
  378.     if (m_hScrollBmp) 
  379.     {
  380.         VERIFY( ::DeleteObject( m_hScrollBmp ));
  381.     }
  382.     
  383.     if (m_Pane != NULL)
  384.     {
  385.         m_Notification->data = NULL;
  386.         XP_UnregisterNavCenter(m_Pane);
  387.         HT_DeletePane(m_Pane);
  388.     }
  389.  
  390.     if (m_scrollUp)
  391.         delete m_scrollUp;
  392.     if (m_scrollDown)
  393.         delete m_scrollDown;
  394.  
  395.     delete m_Notification;
  396.     if(m_pDropTarget) 
  397.     {
  398.         m_pDropTarget->Revoke();
  399.         delete m_pDropTarget;
  400.         m_pDropTarget = NULL;
  401.     }
  402. }
  403.  
  404. void CSelector::OnDraw(CDC* pDC) 
  405. {
  406. }
  407.  
  408. int CSelector::OnCreate(LPCREATESTRUCT lpCreateStruct)
  409. {
  410.     if(!m_pDropTarget) {
  411.         m_pDropTarget = new CSelectorDropTarget(this);
  412.         m_pDropTarget->Register(this);
  413.     }
  414.     CRect tempRect(0, 0, 1, 1);
  415.     m_scrollUp->Create("", BS_OWNERDRAW | BS_PUSHBUTTON , tempRect, this, SCROLLID);
  416.     m_scrollDown->Create("", BS_OWNERDRAW | BS_PUSHBUTTON , tempRect, this, SCROLLID+1);
  417.     m_scrollUp->SetWindowPos( &wndTopMost, 0, 0, 1, 1, 0);
  418.     m_scrollDown->SetWindowPos( &wndTopMost, 0, 0, 1, 1, 0);
  419.   
  420. #ifdef XP_WIN32
  421.     ::SetClassLong(GetSafeHwnd(), GCL_HBRBACKGROUND, (COLOR_BTNFACE + 1));
  422. #else
  423.     ::SetClassWord(GetSafeHwnd(), GCW_HBRBACKGROUND, (COLOR_BTNFACE + 1));
  424. #endif
  425.  
  426.     return 0;
  427. }
  428.  
  429. void CSelector::SelectNthView(int i)
  430. {
  431.     HT_View theView = HT_GetNthView(m_Pane, i);
  432.     if (theView && HT_GetViewFEData(theView))
  433.     {
  434.         CSelectorButton* pButton = (CSelectorButton*)HT_GetViewFEData(theView);
  435.         pButton->OnAction();
  436.     }
  437. }
  438.  
  439. BOOL CSelector::IsTreeVisible()
  440. {
  441.     return m_pCurView != NULL;
  442. }
  443.  
  444. void CSelector::SetCurrentView(CSelectorButton* pButton)
  445. {
  446.     CView* pView = pButton->GetView();
  447.  
  448.     if (m_pCurButton) 
  449.     {
  450.         m_pCurButton->SetDepressed(FALSE);
  451.     }
  452.     m_pCurButton = pButton;
  453.     m_pCurButton->SetDepressed(TRUE);
  454.     if (m_pCurView != pView ) 
  455.     {
  456.         if (m_pCurView)
  457.             m_pCurView->ShowWindow(SW_HIDE);
  458.         m_pCurView = pView;
  459.         GetParentFrame()->SetActiveView( m_pCurView);
  460.             
  461.         ((CNSNavFrame*)GetParentFrame())->GetNavMenuBar()->UpdateView(m_pCurButton, m_pCurButton->GetHTView());
  462.         ((CNSNavFrame*)GetParentFrame())->UpdateTitleBar(m_pCurButton->GetHTView());
  463.     }
  464.         
  465.     // adjust the window. here.
  466.     m_pCurView->ShowWindow(SW_SHOW);
  467.     if(m_pCurView->GetParent()->IsKindOf(RUNTIME_CLASS(CContentView))) 
  468.     {
  469.         CContentView* contentView = (CContentView*)m_pCurView->GetParent();
  470.         contentView->CalcChildSizes();
  471.     }
  472.         
  473.     m_pCurView->SetFocus();
  474. }
  475.  
  476. void CSelector::UnSelectAll()
  477. {
  478.     if (m_pCurButton)
  479.         m_pCurButton->SetDepressed(FALSE);
  480.     m_pCurButton = 0;
  481.     if (m_pCurView)
  482.     {    
  483.         m_pCurView->ShowWindow(SW_HIDE);
  484.         m_pCurView = 0;
  485.         GetParentFrame()->SetActiveView( m_pCurView);
  486.     }
  487.  
  488.     ((CNSNavFrame*)GetParentFrame())->GetNavMenuBar()->UpdateView(NULL, NULL);
  489. }
  490.  
  491. CView* CSelector::GetCurrentView()
  492. {
  493.     return m_pCurView;
  494. }
  495.  
  496. CSelectorButton* CSelector::GetCurrentButton()
  497. {
  498.     return m_pCurButton;
  499. }
  500.  
  501. void CSelector::OnSize( UINT nType, int cx, int cy )
  502. {
  503.     if (cy > m_boundingBox.Height() && m_scrollPos > 0) 
  504.     {  // resize bigger need to scroll down.
  505.         ScrollWindowEx( 0, SCROLLSTEP, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE); 
  506.         m_scrollPos -= SCROLLSTEP;
  507.  
  508.     }
  509.     int32 dockStyle = ((CNSNavFrame*)GetParent())->GetDockStyle();
  510.     if (dockStyle == DOCKSTYLE_HORZTOP || dockStyle == DOCKSTYLE_HORZBOTTOM) 
  511.     {
  512.         int left = cx-m_hScrollBmpSize.cx;
  513.         m_scrollUp->MoveWindow(0, 0, m_hScrollBmpSize.cx,  m_hScrollBmpSize.cy);
  514.         m_scrollUp->setBoundingBox(0, 0, m_hScrollBmpSize.cx, m_hScrollBmpSize.cy);
  515.         m_scrollDown->MoveWindow(left, 0, m_hScrollBmpSize.cx ,  m_hScrollBmpSize.cy);
  516.         m_scrollDown->setBoundingBox(left, 0, left + m_hScrollBmpSize.cx, m_hScrollBmpSize.cy);
  517.     }
  518.     else 
  519.     {
  520.         int top = cy - m_hScrollBmpSize.cy;
  521.         int left = cx-m_hScrollBmpSize.cx;
  522.         m_scrollUp->MoveWindow(left, 0, m_hScrollBmpSize.cx,  m_hScrollBmpSize.cy);
  523.         m_scrollUp->setBoundingBox(left, 0, left + m_hScrollBmpSize.cx , m_hScrollBmpSize.cy);
  524.         m_scrollDown->MoveWindow(left, top, m_hScrollBmpSize.cx ,  m_hScrollBmpSize.cy);
  525.         m_scrollDown->setBoundingBox(left, top, left + m_hScrollBmpSize.cx, top + m_hScrollBmpSize.cy);
  526.     }
  527.     ShowScrollButton(NULL);
  528.     GetClientRect(&m_boundingBox);
  529.     RearrangeIcons();
  530. }
  531.  
  532.  
  533.  
  534. void CSelector::ShowScrollButton(CSelectorButton* button)
  535. {
  536.     CRect tempRect;
  537.     CNSNavFrame* pParent = (CNSNavFrame*)GetParent();
  538.     int32 dockstyle = pParent->GetDockStyle();
  539.     GetClientRect(&tempRect);
  540.     // checked if we need to display the scroll button
  541.     if (dockstyle == DOCKSTYLE_FLOATING || dockstyle == DOCKSTYLE_VERTLEFT ||
  542.         dockstyle == DOCKSTYLE_VERTRIGHT) {
  543.         if ((m_ypos - m_hScrollBmpSize.cy) > (tempRect.Height() - ICONYPOS)) {
  544.             m_scrollUp->ShowWindow(SW_SHOW);
  545.             m_scrollDown->ShowWindow(SW_SHOW);
  546.             m_scrollUp->Invalidate();
  547.             m_scrollDown->Invalidate();
  548.         }
  549.         else {
  550.             m_scrollUp->ShowWindow(SW_HIDE);
  551.             m_scrollDown->ShowWindow(SW_HIDE);
  552.         }
  553.     }
  554.     else {
  555.         if ((m_xpos - m_hScrollBmpSize.cx) > (tempRect.Width() - ICONXPOS)) {
  556.             m_scrollUp->ShowWindow(SW_SHOW);
  557.             m_scrollDown->ShowWindow(SW_SHOW);
  558.             m_scrollUp->Invalidate();
  559.             m_scrollDown->Invalidate();
  560.         }
  561.         else {
  562.             m_scrollUp->ShowWindow(SW_HIDE);
  563.             m_scrollDown->ShowWindow(SW_HIDE);
  564.         }
  565.     }
  566. }
  567.  
  568.  
  569. void CSelector::AddViewContext(const char* pTitle, CView* pView, CRDFContentView* pTree, 
  570.                                CPaneCX* htmlPane, HT_View theView)
  571. {
  572.     CSelectorButton* theNSViewButton = new CSelectorButton(this);
  573.  
  574.     // Button meets the view.  View meets the button.
  575.     theNSViewButton->SetHTView(theView); 
  576.     theNSViewButton->SetTreeView(pTree);
  577.  
  578.     HT_SetViewFEData(theView, theNSViewButton);
  579.  
  580.     HT_Resource node = theView ? HT_TopNode(theView) : NULL;
  581.     char* pNodeURL = node ? HT_GetNodeURL(node) : "";
  582.  
  583.     theNSViewButton->Create(this, theApp.m_pToolbarStyle, CSize(60,42), CSize(85, 25), 
  584.                             pTitle,
  585.                             pTitle, pNodeURL, 
  586.                             CSize(23,23), 10, 5, 
  587.                             node,
  588.                             TB_HAS_DRAGABLE_MENU | TB_HAS_TIMED_MENU, pView, htmlPane);
  589.     
  590.     CRect rect;
  591.     rect.left = (long)m_xpos;
  592.     rect.top = (long)m_ypos;
  593.  
  594.     CSize buttonSize = theNSViewButton->GetRequiredButtonSize();
  595.     rect.right = rect.left + buttonSize.cx;
  596.     rect.bottom = rect.top + buttonSize.cy;
  597.  
  598.     CNSNavFrame* pFrame = (CNSNavFrame*)GetParentFrame();
  599.     int32 dockStyle = pFrame->GetDockStyle();
  600.  
  601.     if (dockStyle == DOCKSTYLE_HORZTOP || dockStyle == DOCKSTYLE_HORZBOTTOM)
  602.     {
  603.         m_xpos += BUTTON_WIDTH + 2;
  604.         rect.bottom = rect.top + BUTTON_HEIGHT;
  605.     }
  606.     else 
  607.     {
  608.         m_ypos += buttonSize.cy + 2;
  609.         rect.right = rect.left + BUTTON_WIDTH;
  610.     }
  611. /*
  612.     CString originalText = HT_GetNodeName(theNSViewButton->GetNode());
  613.     int currCount = originalText.GetLength();
  614.         
  615.     // Start off at the maximal string
  616.     CString strTxt = originalText;
  617.  
  618.     CSize theSize = theNSViewButton->GetButtonSizeFromChars(originalText, currCount);
  619.     int horExtent = theSize.cx;
  620.  
  621.     while (horExtent > BUTTON_WIDTH)
  622.     {
  623.         strTxt = originalText.Left(currCount-3) + "...";
  624.         theSize = theNSViewButton->GetButtonSizeFromChars(strTxt, currCount);
  625.         horExtent = theSize.cx;
  626.         currCount--;
  627.     }
  628.  
  629.     theNSViewButton->SetTextWithoutResize(strTxt);
  630. */
  631.  
  632.     ShowScrollButton(theNSViewButton);
  633. }
  634.  
  635.  
  636. void CSelector::PopulatePane()
  637. {
  638.     // Construct the notification struct used by HT
  639.     HT_Notification ns = new HT_NotificationStruct;
  640.     ns->notifyProc = notifyProcedure;
  641.     ns->data = this;
  642.     m_Notification = ns;
  643.     
  644.     // Construct the pane and give it our notification struct
  645.     m_Pane = HT_NewPane(ns);
  646.     HT_SetPaneFEData(m_Pane, this);
  647.     
  648.     //  Inform our XP layer of the new nav center.
  649.     MWContext *pDockedCX = NULL;
  650.     CNSNavFrame *pParentFrame = GetParentFrame()->IsKindOf(RUNTIME_CLASS(CNSNavFrame)) ? (CNSNavFrame*)GetParentFrame() : NULL;
  651.     //  Since the XP layer isn't set up yet, we can't use
  652.     //      XP_IsNavCenterDocked in order to tell
  653.     //      if the window is docked.  Use instead wether or
  654.     //      not the frame has a parent.
  655.     if(pParentFrame && pParentFrame->GetParent()) {
  656.         CFrameGlue *pGlue = CFrameGlue::GetFrameGlue(pParentFrame->GetTopLevelFrame());
  657.         if(pGlue && pGlue->GetMainContext()) {
  658.             pDockedCX = pGlue->GetMainContext()->GetContext();
  659.         }
  660.         ASSERT(pDockedCX);
  661.     }
  662.     XP_RegisterNavCenter(m_Pane, pDockedCX);
  663.  
  664.     // Place any icons that were immediately available.  (The remote ones will trickle in later, and we'll
  665.     // rearrange the selector bar when we get those VIEW_ADDED events.)
  666.     RearrangeIcons();
  667. }
  668.  
  669. void CSelector::ConstructView(HT_View theView)
  670. {
  671.     if (theView == NULL)
  672.         return;
  673.  
  674.     CString viewName = HT_GetNodeName(HT_TopNode(theView));
  675.     
  676.     // Construct the RDF view
  677.     CWnd *theParent = (CWnd *)(((CNSNavFrame*)GetParentFrame())->GetContentView());
  678.  
  679.     DWORD dwCurrentStyle = WS_CHILD;
  680.     
  681.     //  Parent may change depending on view (need more panes).
  682.     CRect rClient(0, 0, 100, 100);
  683.     CContentView *pAltParent = NULL;
  684.     CPaneCX *pCX = NULL;
  685.     if(HT_HasHTMLPane(theView)) 
  686.     {
  687.         pAltParent = new CContentView();
  688.         pAltParent->Create(NULL, "", WS_CHILD, rClient, theParent, NC_IDW_MISCVIEW, NULL);
  689.         pCX = wfe_CreateNavCenterHTMLPain(theView, pAltParent->m_hWnd);
  690.         
  691.         //  Make all other children visible now (we control visibility by being the parent).
  692.         dwCurrentStyle |= WS_VISIBLE;
  693.     }
  694.     if(pAltParent) {
  695.         theParent = (CWnd *)pAltParent;
  696.     }
  697.     theParent->GetClientRect(&rClient);
  698.     
  699.     // Can't use CSelector's m_Pane, because it might not have been initialized yet.  Calls
  700.     // HT_GetPane instead.
  701.     CRDFOutlinerParent* newParent = new CRDFOutlinerParent(HT_GetPane(theView), theView);
  702.     CRDFContentView* newView = new CRDFContentView(newParent);
  703.     
  704.     // Create the windows
  705.     newView->Create( NULL, "", dwCurrentStyle, rClient, theParent, NC_IDW_OUTLINER);
  706.  
  707.     // Initialize the columns, etc.
  708.     newParent->Initialize();
  709.     
  710.     // Name and icon for the view correspond to the name/icon of the top node in the view.
  711.     AddViewContext(viewName, pAltParent ? (CView *)pAltParent : (CView *)newView, newView, pCX, theView);
  712. }
  713.  
  714. void CSelector::DestroyViews()
  715. {
  716.     int viewCount = HT_GetViewListCount(m_Pane);
  717.     for (int i = 0; i < viewCount; i++)
  718.     {
  719.         HT_View v = HT_GetNthView(m_Pane, i);
  720.         if (v != NULL)
  721.         {
  722.             CRDFContentView* theView = (CRDFContentView*)(HT_GetViewFEData(v));
  723.             delete theView;
  724.         }
  725.     }
  726. }
  727.  
  728. BOOL CSelector::OnEraseBkgnd( CDC* pDC )
  729. {
  730.     int i = 0;
  731.     return CWnd::OnEraseBkgnd(pDC);
  732. }
  733.  
  734.  
  735. void CSelector::ScrollSelector()
  736. {
  737.     if (m_scrollDirection ==  SCROLLUP || m_scrollDirection == SCROLLLEFT) {
  738.         if (m_scrollPos  > 0) {
  739.             if (m_scrollDirection ==  SCROLLUP) 
  740.                 ScrollWindowEx( 0, SCROLLSTEP, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE); 
  741.             else 
  742.                 ScrollWindowEx( SCROLLSTEP, 0, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE); 
  743.             m_scrollPos -= SCROLLSTEP;
  744.         }
  745.     } 
  746.     else {
  747.         RECT rect;
  748.         GetClientRect(&rect);
  749.         if (m_scrollDirection ==  SCROLLDOWN) {
  750.             if (m_scrollPos + (rect.bottom - rect.top) < m_ypos) {
  751.                 ScrollWindowEx( 0, -SCROLLSTEP, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE); 
  752.                 m_scrollPos += SCROLLSTEP;
  753.             }
  754.             else if (m_scrollPos + (rect.right - rect.left) < m_xpos) {
  755.                 ScrollWindowEx( -SCROLLSTEP, 0, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE); 
  756.                 m_scrollPos += SCROLLSTEP;
  757.             }
  758.         }
  759.     }
  760.     ShowScrollButton(NULL);
  761.     m_scrollUp->AdjustPos();
  762.     m_scrollDown->AdjustPos();
  763. }
  764.  
  765.  
  766. void CSelector::OnParentNotify( UINT message, LPARAM lParam )
  767. {
  768.     if (message == WM_LBUTTONDOWN) {
  769.         POINT pt;
  770.         pt.x = LOWORD(lParam);  // horizontal position of cursor 
  771.         pt.y = HIWORD(lParam);  // vertical position of cursor 
  772.         CNSNavFrame* pParent = (CNSNavFrame*)GetParent();
  773.         int32 dockStyle = pParent->GetDockStyle();
  774.         if (m_scrollUp->IsPtInRect(pt)) {
  775.             if (dockStyle == DOCKSTYLE_HORZTOP)
  776.                 m_scrollDirection = SCROLLLEFT;
  777.             else
  778.                 m_scrollDirection = SCROLLUP;
  779.         }
  780.         else if (m_scrollDown->IsPtInRect(pt)){     // scroll down.
  781.             if (dockStyle == DOCKSTYLE_HORZBOTTOM)
  782.                 m_scrollDirection = SCROLLRIGHT;
  783.             else
  784.                 m_scrollDirection = SCROLLDOWN;
  785.         }
  786.         ScrollSelector();
  787.     }
  788.     CWnd::OnParentNotify( message, lParam );
  789. }
  790.  
  791. void CSelector::RearrangeIcons()
  792. {
  793.     if (m_Pane == NULL)
  794.         return;
  795.  
  796.     CNSNavFrame* pFrame = (CNSNavFrame*)GetParentFrame();
  797.     int32 dockStyle = pFrame->GetDockStyle();
  798.  
  799.     CRect tempRect;
  800.     if (dockStyle == DOCKSTYLE_HORZTOP || dockStyle == DOCKSTYLE_HORZBOTTOM) 
  801.     {
  802.         m_xpos = ICONXPOS;
  803.         m_ypos = 2;
  804.     }
  805.     else {
  806.         m_xpos = 2;
  807.         m_ypos = ICONYPOS;
  808.     }
  809.     CRect parentRect;
  810.     CSelectorButton* theButton = NULL;
  811.     GetClientRect(&parentRect);
  812.  
  813.     int count = HT_GetViewListCount(m_Pane);
  814.     for (int i = 0; i < count; i++)
  815.     {
  816.         HT_View view = HT_GetNthView(m_Pane, i);
  817.         
  818.         if (view && HT_GetViewFEData(view))
  819.         {
  820.             theButton = (CSelectorButton*)HT_GetViewFEData(view);
  821.         
  822.             CSize buttonSize = theButton->GetRequiredButtonSize();
  823.  
  824.             if (dockStyle == DOCKSTYLE_FLOATING || dockStyle == DOCKSTYLE_VERTLEFT ||
  825.                 dockStyle == DOCKSTYLE_VERTRIGHT) 
  826.             {     // draw icon from top to bottom
  827.                 theButton->MoveWindow((int)m_xpos, (int)m_ypos, 
  828.                     BUTTON_WIDTH, buttonSize.cy, TRUE);
  829.  
  830.                 m_ypos += buttonSize.cy + 2; 
  831.             }
  832.             else 
  833.             {    // draw icon from left to right.
  834.                 theButton->MoveWindow((int)m_xpos, (int)m_ypos, 
  835.                     BUTTON_WIDTH, buttonSize.cy, TRUE);
  836.                 m_xpos += BUTTON_WIDTH + 2;
  837.             }
  838.         }
  839.     }
  840. }
  841.  
  842. CSelectorButton* CSelector::GetButtonFromPoint(CPoint point, BOOL& onButton)
  843. {
  844.     CRect buttonRect;
  845.     onButton = FALSE;
  846.  
  847.     CNSNavFrame* pFrame = (CNSNavFrame*)GetParentFrame();
  848.     int32 dockStyle = pFrame->GetDockStyle();
  849.  
  850.     CSelectorButton* pButton = NULL;
  851.     int count = HT_GetViewListCount(m_Pane);
  852.     for (int i = 0; i < count; i++)
  853.     {
  854.         HT_View view = HT_GetNthView(m_Pane, i);
  855.         
  856.         if (view && HT_GetViewFEData(view))
  857.         {
  858.             pButton = (CSelectorButton*)HT_GetViewFEData(view);
  859.             pButton->GetClientRect(&buttonRect);
  860.             pButton->MapWindowPoints(this, &buttonRect);
  861.         
  862.             if (buttonRect.PtInRect(point))
  863.             {
  864.                 onButton = TRUE;
  865.                 return pButton;
  866.             }
  867.  
  868.             if (dockStyle == DOCKSTYLE_FLOATING || dockStyle == DOCKSTYLE_VERTLEFT ||
  869.                 dockStyle == DOCKSTYLE_VERTRIGHT) 
  870.             {
  871.                 if (point.y <= buttonRect.bottom)
  872.                 return pButton;
  873.             }
  874.             else
  875.             {
  876.                 if (point.x <= buttonRect.right)
  877.                 return pButton;
  878.             }
  879.         }
  880.     }
  881.     return NULL;
  882. }
  883.  
  884. void CSelector::OnTimer(UINT nID)
  885. {
  886.     CWnd::OnTimer(nID);
  887.     if (nID == IDT_PANESWITCH) 
  888.     {
  889.         if (m_hPaneSwitchTimer != 0)
  890.         {
  891.             KillSwitchTimer();
  892.         }
  893.  
  894.         // Do the pane switch
  895.         if (m_pCurButton != GetDragButton())
  896.         {
  897.             // There's actually something that needs to be done.
  898.             if (m_pCurButton) // Something is depressed
  899.                 GetDragButton()->OnAction();
  900.             else    // Nothing is depressed. Use popup menus instead.
  901.                 GetDragButton()->DisplayMenuOnDrag();    
  902.         }
  903.     }
  904. }
  905.  
  906.  
  907. void CSelector::OnLButtonDown (UINT nFlags, CPoint point )
  908. {
  909.     // Called when the user clicks on the menu bar.  Start a drag or collapse the view.
  910.     if (m_pCurButton)
  911.     {
  912.         CRDFContentView* pView = m_pCurButton->GetTreeView();
  913.         if (pView)
  914.             pView->SetFocus();
  915.     }
  916.  
  917.     m_PointHit = point;
  918.     SetCapture();
  919. }
  920.  
  921.  
  922. void CSelector::OnMouseMove(UINT nFlags, CPoint point)
  923. {
  924.     if (GetCapture() == this)
  925.     {
  926.         CNSNavFrame* navFrameParent = (CNSNavFrame*)GetParentFrame();
  927.         
  928.         if (abs(point.x - m_PointHit.x) > 3 ||
  929.             abs(point.y - m_PointHit.y) > 3)
  930.         {
  931.             ReleaseCapture();
  932.  
  933.             // Start a drag
  934.             MapWindowPoints(navFrameParent, &point, 1); 
  935.             navFrameParent->StartDrag(point);
  936.         }
  937.     }
  938. }
  939.  
  940. void CSelector::OnLButtonUp(UINT nFlags, CPoint point)
  941. {
  942.     if (GetCapture() == this) 
  943.     {
  944.         ReleaseCapture();
  945.     }
  946. }
  947.  
  948. void CSelector::OnRButtonDown(UINT nFlags, CPoint point)
  949. {
  950.     m_MenuCommandMap.Clear();
  951.     HT_Cursor theCursor = HT_NewContextualMenuCursor(NULL, PR_TRUE, PR_TRUE);
  952.     CMenu menu;
  953.     ClientToScreen(&point);
  954.     if (menu.CreatePopupMenu() != 0 && theCursor != NULL)
  955.     {
  956.         // We have a cursor. Attempt to iterate
  957.         HT_MenuCmd theCommand; 
  958.         while (HT_NextContextMenuItem(theCursor, &theCommand))
  959.         {
  960.             char* menuName = HT_GetMenuCmdName(theCommand);
  961.             if (theCommand == HT_CMD_SEPARATOR)
  962.                 menu.AppendMenu(MF_SEPARATOR);
  963.             else
  964.             {
  965.                 // Add the command to our command map
  966.                 CRDFMenuCommand* rdfCommand = new CRDFMenuCommand(menuName, theCommand);
  967.                 int index = m_MenuCommandMap.AddCommand(rdfCommand);
  968.                 menu.AppendMenu(MF_ENABLED, index+FIRST_HT_MENU_ID, menuName);
  969.             }
  970.         }
  971.         HT_DeleteCursor(theCursor);
  972.  
  973.         menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this, NULL);    
  974.  
  975.         menu.DestroyMenu();
  976.     }
  977. }
  978.  
  979. BOOL CSelector::OnCommand( WPARAM wParam, LPARAM lParam )
  980. {
  981.     if (wParam >= FIRST_HT_MENU_ID && wParam <= LAST_HT_MENU_ID)
  982.     {
  983.         // A selection was made from the context menu.
  984.         // Use the menu map to get the HT command value
  985.         CRDFMenuCommand* theCommand = (CRDFMenuCommand*)(m_MenuCommandMap.GetCommand((int)wParam-FIRST_HT_MENU_ID));
  986.         if (theCommand)
  987.         {
  988.             HT_MenuCmd htCommand = theCommand->GetHTCommand();
  989.             HT_DoMenuCmd(m_Pane, htCommand);
  990.         }
  991.     }
  992.     return TRUE;
  993. }
  994.  
  995. CSelectorDropTarget::CSelectorDropTarget(CSelector* pParent) 
  996. {
  997.     fd = 0;
  998.     m_pParent = pParent;
  999. }
  1000.  
  1001. CSelectorDropTarget::~CSelectorDropTarget()
  1002. {
  1003.     delete fd;
  1004. }
  1005.  
  1006.  
  1007. BOOL CSelectorDropTarget::OnDrop(CWnd* pWnd, 
  1008.                 COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
  1009. {
  1010.     CSelector* pSelector = (CSelector*)pWnd;
  1011.     HT_View theView = pSelector->GetDragButton()->GetHTView();
  1012.     pSelector->SetDragButton(NULL);
  1013.     if (pSelector->GetSwitchTimer() != 0)
  1014.         pSelector->KillSwitchTimer();
  1015.     if (theView)
  1016.     {
  1017.         // Do a drop.  For now just use drag fractions of 2.
  1018.         RDFGLOBAL_PerformDrop(pDataObject, HT_TopNode(theView), 2);
  1019.     }
  1020.     
  1021.     
  1022.  
  1023. /*
  1024.     if(!pDataObject || !pWnd)
  1025.         return(FALSE);
  1026.  
  1027. #ifdef XP_WIN32
  1028.     // we only handle text at the moment
  1029.     if(! (pDataObject->IsDataAvailable(CF_TEXT) || pDataObject->IsDataAvailable(CF_UNICODETEXT)))
  1030.         return(FALSE);
  1031. #else
  1032.     // we only handle text at the moment
  1033.     if(!pDataObject->IsDataAvailable(CF_TEXT))
  1034.         return(FALSE);
  1035. #endif
  1036.  
  1037.     CSelector * cView = (CSelector *) pWnd;
  1038.  
  1039.     BOOL bUseUnicodeData = FALSE;
  1040.  
  1041.     // get the data
  1042.     HGLOBAL hString = pDataObject->GetGlobalData(CF_TEXT);
  1043.     if(hString == NULL)
  1044.         return(FALSE);
  1045.  
  1046.     // get a pointer to the actual bytes
  1047.     char *  pString = (char *) GlobalLock(hString);    
  1048.     if(!pString)
  1049.         return(FALSE);
  1050.  
  1051.     m_url = pString;
  1052.  
  1053.     GlobalUnlock(hString);
  1054.     if    (strnicmp(m_url, "mailto:", 7) == 0) {    // drag from mail and new
  1055.  
  1056.     //    Generic brain dead interface to GetUrl.
  1057.         pSaveContext = new CSaveCX(NULL, "MCF Viewer", pWnd);
  1058.             //  Create the stream which will do the actual work.
  1059.     #ifndef XP_WIN16
  1060.         pSaveContext->Create(CSaveCX::IDD, m_pParent);
  1061.     #elif defined(DEBUG_hyatt) || defined(DEBUG_mhwang) || defined(DEBUG_rjc) || defined(DEBUG_guha)
  1062.     // TODO -WIND16 Fix the saving of MCF correctly, and stop using static strings
  1063.     #endif
  1064.         fd = 0;
  1065.         NET_StreamClass *pStream = NET_NewStream("Saving MCF file",
  1066.             MCFSaveWrite,
  1067.             MCFSaveComplete,
  1068.             MCFSaveAbort,
  1069.             MCFSaveReady,
  1070.             this,
  1071.             pSaveContext->GetContext());
  1072.  
  1073.         pSaveContext->SetSecondaryStream(pStream);
  1074.         //    Load it.
  1075.         URL_Struct *pUrlStruct = NET_CreateURLStruct(m_url, NET_DONT_RELOAD);
  1076.         pSaveContext->GetUrl(pUrlStruct, FO_CACHE_AND_SAVE_AS, TRUE, FALSE);
  1077.     }
  1078.     else 
  1079.     {
  1080.         CWnd* pWindowHit =  m_pParent->ChildWindowFromPoint( point );
  1081.         if (pWindowHit)
  1082.         {
  1083.             CSelectorButton* theButton = (CSelectorButton*)pWindowHit;
  1084.             CPoint point(-1, -1);
  1085.             return theButton->GetView()->OnDrop(pDataObject, dropEffect, point);
  1086.         }
  1087.         else 
  1088.         { // create a new work space.
  1089.             HT_NewWorkspace(m_url.GetBuffer(m_url.GetLength()), m_pParent, m_pParent->GetHTPane());
  1090.         }
  1091.     }
  1092.     */
  1093.     return(TRUE);
  1094.  
  1095. }
  1096.  
  1097.  
  1098. DROPEFFECT CSelectorDropTarget::OnDragEnter(CWnd* pWnd, 
  1099.                 COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
  1100. {
  1101.     return OnDragOver(pWnd, pDataObject, dwKeyState, point);
  1102. }
  1103.  
  1104. DROPEFFECT CSelectorDropTarget::OnDragOver(CWnd* pWnd, 
  1105.                 COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
  1106. {
  1107.     CSelector* pSelector = (CSelector*)pWnd;
  1108.     BOOL onButton;
  1109.  
  1110.     CSelectorButton* pButton = pSelector->GetButtonFromPoint(point, onButton);
  1111.     HT_Resource theNode = pButton ? pButton->GetNode() : NULL;
  1112.     
  1113.     // Give some drag feedback.  For now just use drag fractions of 2.
  1114.     DROPEFFECT answer = RDFGLOBAL_TranslateDropAction(theNode, pDataObject, 2);
  1115.  
  1116.     if (pButton != pSelector->GetDragButton()) // User is over a different button
  1117.     {
  1118.         if (pSelector->GetSwitchTimer() != 0)
  1119.             pSelector->KillSwitchTimer();    // Kill the existing pane switch timer.
  1120.         
  1121.         pSelector->SetDragButton(pButton);
  1122.         
  1123.         if (answer != DROPEFFECT_NONE) // Set the pane switching timer if the user can drop here.
  1124.             pSelector->SetSwitchTimer();
  1125.         else
  1126.         {
  1127.             // Kill any menus that are up.
  1128.             CDropMenu* theLastMenu = CDropMenu::GetLastDropMenu();
  1129.             if(theLastMenu !=NULL)
  1130.             {
  1131.                 //we only want one drop menu open at a time, so close the last one if one is
  1132.                 //still open. 
  1133.                 theLastMenu->Deactivate();
  1134.                 CDropMenu::SetLastDropMenu(NULL);
  1135.             }
  1136.         }
  1137.     }
  1138.  
  1139.     return answer;
  1140. }
  1141.  
  1142. void CSelectorDropTarget::OnDragLeave(CWnd* pWnd)
  1143. {
  1144.     CSelector* pSelector = (CSelector*)pWnd;
  1145.     pSelector->SetDragButton(NULL);
  1146.     if (pSelector->GetSwitchTimer() != 0)
  1147.     {
  1148.         pSelector->KillSwitchTimer();
  1149.     }
  1150. }
  1151.  
  1152.  
  1153. IMPLEMENT_DYNAMIC(CNavSelScrollButton, CButton)
  1154. BEGIN_MESSAGE_MAP(CNavSelScrollButton, CButton)
  1155.     //{{AFX_MSG_MAP(CMainFrame)
  1156. //    ON_WM_LBUTTONUP()
  1157.         // NOTE - the ClassWizard will add and remove mapping macros here.
  1158.         //    DO NOT EDIT what you see in these blocks of generated code !
  1159.     //}}AFX_MSG_MAP
  1160. END_MESSAGE_MAP()
  1161.  
  1162. CNavSelScrollButton::CNavSelScrollButton(HBITMAP hBmp, int width, int index, int height) 
  1163. {
  1164.     m_hbmp = hBmp; 
  1165.     m_width = width;
  1166.     m_index = index;
  1167.     m_height = height;
  1168.     m_selected = FALSE;
  1169. }
  1170.  
  1171. void CNavSelScrollButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
  1172. {
  1173.     if (lpDrawItemStruct->itemAction == ODA_FOCUS  )
  1174.         return; 
  1175.     if ( m_hbmp ) {
  1176.         RECT rect; 
  1177.         GetClientRect(&rect);
  1178.         int index = m_index; // normal state bitmap.
  1179.         HDC hdcBitmap = ::CreateCompatibleDC( lpDrawItemStruct->hDC );
  1180.  
  1181.         HBITMAP hbmOld = (HBITMAP) ::SelectObject( hdcBitmap, m_hbmp );
  1182.  
  1183.         if ((lpDrawItemStruct->itemAction == ODA_SELECT) && 
  1184.             ((lpDrawItemStruct->itemState & ODS_SELECTED) == ODS_SELECTED)) {
  1185.             if (m_selected) {
  1186.                 m_selected = FALSE;
  1187.             }
  1188.             else {
  1189.                 m_selected = TRUE;
  1190.                 index = m_index + 1;  // selected state bitmap.
  1191.             }
  1192.         }
  1193.         FEU_TransBlt( lpDrawItemStruct->hDC, 
  1194.                       lpDrawItemStruct->rcItem.right - m_width, 
  1195.                       lpDrawItemStruct->rcItem.top, 
  1196.                       m_width, m_height,
  1197.                       hdcBitmap,
  1198.                       index * m_width, 0 ,WFE_GetUIPalette(GetParentFrame())
  1199.                      );
  1200.  
  1201.         ::SelectObject( hdcBitmap, hbmOld );
  1202.         ShowWindow(SW_SHOW);
  1203.         VERIFY( ::DeleteDC( hdcBitmap ));
  1204.         CRgn pRgn;
  1205.         pRgn.CreateRectRgn( m_boundBox.left, m_boundBox.top, 
  1206.                             m_boundBox.right, m_boundBox.bottom );
  1207.         GetParent()->ValidateRgn( &pRgn );
  1208.         pRgn.DeleteObject();
  1209.     }
  1210. }
  1211.  
  1212.  
  1213.  
  1214.  
  1215. unsigned int MCFSaveReady(NET_StreamClass *stream)    
  1216. {
  1217.     //    Get our save context out of the data object.
  1218.     CSelectorDropTarget* pDropTarget = (CSelectorDropTarget*)stream->data_object;    
  1219.     if (!pDropTarget->fd) {
  1220.         strcpy(pDropTarget->fileName, WH_TempFileName(xpTemporary, "mcf", ".mcf"));
  1221.         pDropTarget->fd = new CFile(pDropTarget->fileName, CFile::modeCreate | CFile::modeWrite );
  1222.     }
  1223.     return (MAX_WRITE_READY);
  1224. }
  1225.  
  1226. int MCFSaveWrite(NET_StreamClass *stream, const char *pWriteData, int32 iDataLength)    
  1227. {
  1228.     CSelectorDropTarget* pDropTarget = (CSelectorDropTarget*)stream->data_object;    
  1229.     if (!pDropTarget->fd) {
  1230.         strcpy(pDropTarget->fileName, WH_TempFileName(xpTemporary, "mcf", ".mcf"));
  1231.         pDropTarget->fd = new CFile(pDropTarget->fileName, CFile::modeCreate | CFile::modeWrite );
  1232.     }
  1233.     pDropTarget->fd->Write( pWriteData, (UINT)iDataLength );
  1234.  
  1235.     //    Return the amount written, or error.
  1236.     return((UINT)iDataLength);
  1237. }
  1238.  
  1239. void MCFSaveComplete(NET_StreamClass *stream)    
  1240. {
  1241.     CSelectorDropTarget* pDropTarget = (CSelectorDropTarget*)stream->data_object;    
  1242.     pDropTarget->fd->Close( );
  1243. /*
  1244.     HT_NewWorkspace(pDropTarget->fileName, pDropTarget->m_pParent, pDropTarget->m_pParent->GetHTPane());
  1245. */
  1246. }
  1247. void MCFSaveAbort(NET_StreamClass *stream, int iStatus)    
  1248. {    
  1249. }
  1250.  
  1251.