home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / gui / CDragBarContainer.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  16.5 KB  |  571 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. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  20. //    CDragBarContainer.cp
  21. //
  22. //
  23. //    NOTE: It is assumed that the first level sub views of this container are
  24. //    either CDragBar's or the CDragBarDockControl.
  25. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  26.  
  27. #include "CDragBar.h"
  28. #include "CDragBarContainer.h"
  29. #include "CDragBarDockControl.h"
  30. #include "CDragBarDragTask.h"
  31. #include "UGraphicGizmos.h"
  32.  
  33. #include <UMemoryMgr.h>
  34. #include <LArray.h>
  35. #include <LArrayIterator.h>
  36. #include <Drag.h>
  37.  
  38. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  39. //    Ñ    
  40. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  41.  
  42. CDragBarContainer::CDragBarContainer(LStream* inStream)
  43.     :    CBrokeredView(inStream),
  44.         LDropArea(GetMacPort()),
  45.         mBars(sizeof(CDragBar*))
  46. {
  47.     *inStream >> mBarListResID;
  48.     mDock = NULL;
  49.     
  50.     SetRefreshAllWhenResized(false);
  51. }
  52.  
  53. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  54. //    Ñ    
  55. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  56.  
  57. CDragBarContainer::~CDragBarContainer()
  58. {
  59. }
  60.  
  61. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  62. //    Ñ    
  63. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  64.  
  65. void CDragBarContainer::FinishCreateSelf(void)
  66. {
  67.     CBrokeredView::FinishCreateSelf();
  68.  
  69.     // We need to get the dock first so that when we initialize the initial 
  70.     // state of the bars we have somewhere to put them.
  71.     mDock = dynamic_cast<CDragBarDockControl*>(FindPaneByID(CDragBarDockControl::class_ID));
  72.     Assert_(mDock != NULL);
  73.     mDock->AddListener(this);
  74.  
  75.     StResource    theIDList('RidL', mBarListResID);
  76.     {
  77.         StHandleLocker theLock(theIDList);
  78.         LDataStream theBarStream(*theIDList.mResourceH, ::GetHandleSize(theIDList));
  79.         
  80.         Int16 theItemCount;
  81.         theBarStream >> theItemCount;    
  82.         for (Int16 i = 0; i < theItemCount; i++)
  83.             {
  84.             PaneIDT thePaneID;
  85.             theBarStream >> thePaneID;
  86.             
  87.             CDragBar* theBar = dynamic_cast<CDragBar*>(FindPaneByID(thePaneID));
  88.             Assert_(theBar != NULL);
  89.             
  90.             if (theBar->IsDocked())
  91.                 mDock->AddBarToDock(theBar);
  92.  
  93.             mBars.InsertItemsAt(1,     LArray::index_Last, &theBar);
  94.             theBar->AddListener(this);
  95.             }
  96.     }
  97.     
  98.     AdjustContainer();
  99.     AdjustDock();
  100.     
  101.     // Because new toolbar drag bars could adjust their frames
  102.     // at FinishCreateSelf time, call RepositionBars
  103.     RepositionBars();
  104. }
  105.  
  106. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  107. //    Ñ    
  108. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  109.  
  110. void CDragBarContainer::ListenToMessage(
  111.     MessageT            inMessage,
  112.     void*                ioParam)
  113. {
  114.     if (inMessage == msg_DragBarCollapse)
  115.         {
  116.         CDragBar* theBar = (CDragBar*)ioParam;        
  117.         NoteCollapseBar(theBar);
  118.         }
  119.     else if (inMessage == msg_DragBarExpand)
  120.         {
  121.         CDragBar* theBar = (CDragBar*)ioParam;        
  122.         NoteExpandBar(theBar);
  123.         }
  124.     
  125. }
  126.  
  127. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  128. //    Ñ    
  129. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  130.  
  131. void CDragBarContainer::SavePlace(LStream *outPlace)
  132. {
  133.     *outPlace << mBars.GetCount();
  134.  
  135.     CDragBar* theBar;
  136.     LArrayIterator theIter(mBars, LArrayIterator::from_Start);
  137.     while (theIter.Next(&theBar))
  138.         {
  139.         *outPlace << theBar->GetPaneID();
  140.         *outPlace << theBar->IsDocked();
  141.         *outPlace << theBar->IsAvailable();
  142.         }
  143.         
  144.     mDock->SavePlace(outPlace);
  145.  
  146. }
  147.  
  148. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  149. //    Ñ    
  150. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  151.  
  152. void CDragBarContainer::RestorePlace(LStream *inPlace)
  153. {
  154.     Int32 theBarCount;
  155.     *inPlace >> theBarCount;
  156.     for (Int32 theIndex = LArray::index_First; theIndex <= theBarCount; theIndex++)
  157.     {
  158.         PaneIDT thePaneID;
  159.         *inPlace >> thePaneID;
  160.         
  161.         Boolean bIsDocked;
  162.         *inPlace >> bIsDocked;
  163.         
  164.         Boolean bIsAvailable;
  165.         *inPlace >> bIsAvailable;
  166.         
  167.         CDragBar* theBar = dynamic_cast<CDragBar*>(FindPaneByID(thePaneID));
  168.         Assert_(theBar != NULL);
  169.     
  170.         // First we want to place the bar in the same position in the
  171.         // bar array as it was before.  We can tell that by its position
  172.         // from when it was saved out.    
  173.         ArrayIndexT theBarIndex = mBars.FetchIndexOf(&theBar);
  174.         Assert_(theBarIndex != LArray::index_Bad);
  175.         mBars.MoveItem(theBarIndex, theIndex);
  176.         
  177.         // Now we need to sync the state of the bar properly.
  178.         if (bIsDocked && !theBar->IsDocked())
  179.             mDock->AddBarToDock(theBar);
  180.         if (bIsAvailable)
  181.             theBar->Show();
  182.         else
  183.             theBar->Hide();
  184.         theBar->SetAvailable(bIsAvailable);
  185.     }
  186.     
  187.  
  188.     mDock->RestorePlace(inPlace);
  189.  
  190.     RepositionBars();
  191.     AdjustContainer();
  192.     AdjustDock();
  193. }
  194.  
  195. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  196. //    Ñ Hides the drag bar from the container AND dock without changing the docking
  197. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  198. void CDragBarContainer::HideBar(CDragBar* inBar, Boolean inRefresh)
  199. { // hide drag bar
  200.     if (inBar->IsAvailable())
  201.     {
  202.         if (!inBar->IsDocked()) inBar->Hide(); // hide if undocked
  203.         mDock->HideBar(inBar);
  204.         inBar->SetAvailable(false);
  205.         
  206.         RepositionBars();
  207.         AdjustContainer();
  208.         AdjustDock();
  209.         if (inRefresh) Refresh();
  210.     }
  211. }
  212.  
  213. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  214. //    Ñ Show the drag bar without changing the docking
  215. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  216. void CDragBarContainer::ShowBar(CDragBar* inBar, Boolean inRefresh)
  217. {
  218.     if (!inBar->IsAvailable())
  219.     {
  220.         if (!inBar->IsDocked()) inBar->Show(); // show if undocked
  221.         mDock->ShowBar(inBar);
  222.         inBar->SetAvailable(true);
  223.  
  224.         RepositionBars();
  225.         AdjustContainer();
  226.         AdjustDock();
  227.         if (inRefresh) Refresh();
  228.     }
  229. }
  230.  
  231. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  232. //    Ñ    
  233. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  234.  
  235. void CDragBarContainer::NoteCollapseBar(CDragBar* inBar)
  236. {
  237.     FocusDraw();
  238.  
  239.     // 3/6/97 pkc
  240.     // When inBar is NULL, we just want to adjust things, but we
  241.     // don't need to add a bar to the dock
  242.     if (inBar)
  243.         mDock->AddBarToDock(inBar);
  244.  
  245.     RepositionBars();
  246.     AdjustContainer();
  247.     AdjustDock();
  248.     Refresh();
  249. }
  250.  
  251. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  252. //    Ñ    
  253. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  254.  
  255. void CDragBarContainer::NoteExpandBar(CDragBar* inBar)
  256. {
  257.     FocusDraw();
  258.  
  259.     mDock->RemoveBarFromDock(inBar);
  260.     AdjustDock(); // show or hide as appropriate
  261.     
  262.     RepositionBars();
  263.     AdjustContainer();
  264.     Refresh();
  265. }
  266.  
  267. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  268. //    Ñ    
  269. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  270.  
  271. void CDragBarContainer::RepositionBars(void)
  272. {
  273.     Rect theContainerFrame;
  274.     CalcLocalFrameRect(theContainerFrame);
  275.  
  276.     Int32 theHeight = theContainerFrame.top;
  277.     CDragBar* theBar;
  278.     LArrayIterator theIter(mBars, LArrayIterator::from_Start);
  279.     while (theIter.Next(&theBar))
  280.         {
  281.         if (theBar->IsDocked())        // Docked bars are ignored
  282.             continue;
  283.         if (!theBar->IsAvailable())    // Unavailable (hidden from container and dock)
  284.             continue;
  285.  
  286.         SDimension16 theBarSize;
  287.         theBar->GetFrameSize(theBarSize);
  288.         theBar->PlaceInSuperFrameAt(theContainerFrame.left, theHeight, false);
  289.  
  290.         theHeight += theBarSize.height;
  291.         }
  292. }
  293.  
  294. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  295. //    Ñ    
  296. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  297.  
  298. void CDragBarContainer::SwapBars(
  299.     CDragBar*             inSourceBar, 
  300.     CDragBar*            inDestBar,
  301.     Boolean                inRefresh)
  302. {
  303.     if (inSourceBar == inDestBar)
  304.         return;
  305.     
  306.     // Get the indeces and swap the bars in the array    
  307.     ArrayIndexT theSourceIndex = mBars.FetchIndexOf(&inSourceBar);
  308.     Assert_(theSourceIndex != LArray::index_Bad);
  309.     
  310.     ArrayIndexT theDestIndex = mBars.FetchIndexOf(&inDestBar);
  311.     Assert_(theDestIndex != LArray::index_Bad);
  312.  
  313.     mBars.SwapItems(theSourceIndex, theDestIndex);
  314.  
  315.     // align the indeces so we can loop up from one to another.
  316.     if (theSourceIndex > theDestIndex)
  317.         {
  318.         ArrayIndexT theTemp = theSourceIndex;
  319.         theSourceIndex = theDestIndex;
  320.         theDestIndex = theTemp;
  321.         }
  322.  
  323.     // Now we need to invalidate all of the bars between, and including,
  324.     // the source and destination.
  325.     
  326.     FocusDraw();
  327.     while (theSourceIndex <= theDestIndex)
  328.         {
  329.         CDragBar* theBar = NULL;
  330.         mBars.FetchItemAt(theSourceIndex, &theBar);
  331.         Assert_(theBar != NULL);
  332.         
  333.         Rect thePortFrame;
  334.         theBar->CalcPortFrameRect(thePortFrame);
  335.         theBar->InvalPortRect(&thePortFrame);
  336.  
  337.         theSourceIndex++;
  338.         }
  339.         
  340.     if (inRefresh)
  341.         {
  342.         RepositionBars();
  343.         UpdatePort();        // expensive call!!! use sparingly
  344.         }
  345. }
  346.  
  347. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  348. //    Ñ    
  349. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  350.  
  351. void CDragBarContainer::AdjustContainer(void)
  352. {
  353.     // First get our frame size, we need the width.
  354.     SDimension16 theNewSize;
  355.     GetFrameSize(theNewSize);
  356.  
  357.     // The height is the sum of the non-docked bars
  358.     // If all bars are docked, the size is the height of the dock
  359.     theNewSize.height = 0;
  360.         
  361.     CDragBar* theBar;
  362.     LArrayIterator theIter(mBars, LArrayIterator::from_Start);
  363.     while (theIter.Next(&theBar))
  364.         {
  365.         if (theBar->IsDocked())    // Docked bars are ignored.
  366.             continue;
  367.         if (!theBar->IsAvailable())    // Unavailable (hidden from container and dock)
  368.             continue;
  369.     
  370.         SDimension16 theBarSize;
  371.         theBar->GetFrameSize(theBarSize);
  372.         theNewSize.height += theBarSize.height;
  373.         }
  374.  
  375.     SDimension16 theDockSize;
  376.     mDock->GetFrameSize(theDockSize);
  377.  
  378.     if (mDock->HasDockedBars())
  379.         theNewSize.height += theDockSize.height;
  380.         
  381.     ResizeFrameTo(theNewSize.width, theNewSize.height, true);
  382. }
  383.  
  384. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  385. //    Ñ    
  386. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  387.  
  388. void CDragBarContainer::AdjustDock(void)
  389. {
  390.     if (mDock->HasDockedBars())
  391.         mDock->Show();
  392.     else
  393.         mDock->Hide();
  394. }
  395.  
  396. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  397. //
  398. #pragma mark --- DROP AREA BEHAVIOUR ---
  399. //
  400. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  401.  
  402. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  403. //    Ñ    PointInDropArea
  404. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  405. //    Return whether a Point, in Global coords, is inside a DropArea
  406.  
  407. Boolean CDragBarContainer::PointInDropArea(
  408.     Point    inPoint)
  409. {
  410.     GlobalToPortPoint(inPoint);
  411.     return IsHitBy(inPoint.h, inPoint.v);
  412. }
  413.  
  414. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  415. //    Ñ    
  416. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  417.  
  418. Boolean CDragBarContainer::ItemIsAcceptable(
  419.     DragReference        inDragRef,
  420.     ItemReference        inItemRef)
  421. {
  422.     Boolean bIsAcceptable = false;
  423.     
  424.     FlavorFlags    theFlags;
  425.     OSErr theErr = ::GetFlavorFlags(inDragRef, inItemRef, Flavor_DragBar, &theFlags);
  426.     if (theErr == noErr)
  427.         {
  428.         DragAttributes theAttributes;
  429.         theErr = ::GetDragAttributes(inDragRef, &theAttributes);
  430.         if (theErr == noErr)
  431.             bIsAcceptable = (theAttributes & kDragInsideSenderWindow) != 0;
  432.         }
  433.     
  434.     return bIsAcceptable;
  435. }
  436.  
  437.  
  438. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  439. //    Ñ    EnterDropArea
  440. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  441. //    A Drag is entering a DropArea. This call will be followed by a
  442. //    corresponding LeaveDropArea call (when the Drag moves out of the
  443. //    DropArea or after the Drag is received by this DropArea).
  444. //
  445. //    If the DropArea can accept the Drag and the Drag is coming from outside
  446. //    the DropArea, hilite the DropArea
  447.  
  448. void CDragBarContainer::EnterDropArea(
  449.     DragReference    /* inDragRef */,
  450.     Boolean            /* inDragHasLeftSender */)
  451. {
  452.     // NULL IMPLEMENTATION
  453.     // No hiliting necessary.
  454. }
  455.  
  456.  
  457. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  458. //    Ñ    LeaveDropArea
  459. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  460. //    A Drag is leaving a DropArea. This call will have been preceded by
  461. //    a corresponding EnterDropArea call.
  462. //
  463. //    Remove hiliting of the DropArea if necessary
  464.  
  465. void CDragBarContainer::LeaveDropArea(
  466.     DragReference    /* inDragRef */)
  467. {
  468.     // No hiliting necessary.
  469.     mCanAcceptCurrentDrag = false;
  470. }
  471.  
  472.  
  473. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  474. //    Ñ    InsideDropArea
  475. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  476. //    Track a Drag while it is inside a DropArea. This function is called
  477. //    repeatedly while an acceptable Drag is inside a DropArea.
  478. //
  479. //     This more difficult than it needs to be, because  PowerPlant does not pass the refCon
  480. //    through to this routine.  If it did, I could easily get at the tracking bar.
  481. //    Instead I need to go through the drag item reference number to get the
  482. //    task, and then get the tracking bar.
  483.  
  484. void CDragBarContainer::InsideDropArea(DragReference inDragRef)
  485. {
  486.     FocusDraw();
  487.     
  488.     Point theMouse, thePinnedMouse;
  489.     OSErr theErr = ::GetDragMouse(inDragRef, &theMouse, &thePinnedMouse);
  490.     if (theErr != noErr)
  491.     {
  492.         return;
  493.     }
  494.  
  495.     GlobalToPortPoint(theMouse);
  496.     LPane* thePane = FindShallowSubPaneContaining(theMouse.h, theMouse.v);
  497.     
  498.     // We have the special knowledge that the top level sub panes
  499.     // can only be other drag bars, or the dock.  
  500.  
  501.     CDragBar* theBar = dynamic_cast<CDragBar*>(thePane);
  502.     if (theBar != NULL)
  503.         {
  504.         CDragBarDragTask* theTask = NULL;
  505.         theErr = ::GetDragItemReferenceNumber(inDragRef, 1, (ItemReference*)(&theTask));
  506.         if (theErr != noErr)
  507.         {
  508.             return;
  509.         }
  510.  
  511.  
  512.         // See if we're over a bar, and it's not the one we're dragging
  513.         CDragBar* theTrackingBar = theTask->GetTrackingBar();
  514.         if (theBar != theTrackingBar)
  515.             {
  516.             ArrayIndexT theBarPosition;
  517.             theBarPosition = mBars.FetchIndexOf(&theBar);
  518.             
  519.             ArrayIndexT theTrackPosition;
  520.             theTrackPosition = mBars.FetchIndexOf(&theTrackingBar);
  521.             
  522.             // OK, we have the indeces which correspond to the bars' top to
  523.             // bottom ordering on the screen.  To prevent violent swapping of the bars,
  524.             // we only want to swap if the point has passed through the mid horizontal
  525.             // point of the bar in the direction leading away from the current tracking
  526.             // bar.
  527.             
  528.             Rect theBarPortFrame;
  529.             theBar->CalcPortFrameRect(theBarPortFrame);
  530.  
  531.             Int16 theMidLine = theBarPortFrame.top + (RectHeight(theBarPortFrame) / 2);
  532.  
  533.             Boolean bShouldSwap;
  534.             if ((theBarPosition < theTrackPosition) && (theMouse.v <= theMidLine))
  535.                 bShouldSwap = true;
  536.             else if ((theBarPosition > theTrackPosition) && (theMouse.v >= theMidLine))
  537.                 bShouldSwap = true;
  538.             else
  539.                 bShouldSwap = false;
  540.  
  541.             if (bShouldSwap)            
  542.                 SwapBars(theTrackingBar, theBar, true);
  543.             }
  544.         }
  545. }
  546.  
  547. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  548. //    Ñ    ReceiveDragItem
  549. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  550. //    Process an Item which has been dragged into a DropArea
  551. //
  552. //    This function gets called once for each Item contained in a completed
  553. //    Drag. The Item will have returned true from ItemIsAcceptable().
  554. //
  555. //    The DropArea is focused upon entry and inItemBounds is specified
  556. //    in the local coordinates of the DropArea.
  557.  
  558. void CDragBarContainer::ReceiveDragItem(
  559.     DragReference    /* inDragRef */,
  560.     DragAttributes    /* inDragAttrs */,
  561.     ItemReference    /* inItemRef */,
  562.     Rect&            /* inItemBounds */)    // In Local coordinates
  563. {
  564. }
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.