home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / mac / UserInterface / UTearOffPalette.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  35.5 KB  |  1,138 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. // author: atotic
  21. // See UTearOffPalette.h for usage instructions and design notes
  22. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  23.  
  24. #include "UTearOffPalette.h"
  25. #include "prtypes.h"
  26. #include "CToolbarModeManager.h"
  27. #include "CToolbarPatternBevelView.h"
  28. #include "prefapi.h"
  29. #include "uapp.h"
  30.  
  31. // PowerPlant
  32. #include <LStream.h>
  33. #include <URegions.h>
  34. #include <LArray.h>
  35. #include <LArrayIterator.h>
  36.  
  37. #define FLOAT_ID -19844    // Same define is in UFloatWindow.r
  38. #define SIDE_FLOAT_ID -19845    // Same define is in UFloatWindow.r
  39.  
  40. #pragma mark CTearOffBar
  41. #pragma mark -
  42.  
  43. // ---------------------------------------------------------------------------
  44. //        Ñ Constructor from stream
  45. // ---------------------------------------------------------------------------
  46. // Read in the data
  47.  
  48. CTearOffBar::CTearOffBar(LStream* inStream) : LView(inStream)
  49. {
  50.     *inStream >> fFloatingSubpaneID;
  51.     *inStream >> fInPlaceSubpaneID;
  52.     *inStream >> fAutoResize;
  53.     *inStream >> fVisibility;
  54.     *inStream >> fTitle;
  55.     *inStream >> fSideTitle;
  56.     *inStream >> fDisablePaletteWithWindow;
  57.  
  58.     fOriginalFrameSize = mFrameSize;
  59.     fShown = false;
  60.     fTransparentPane = 0;
  61.     fAllowClickDrag = false;
  62. }
  63.  
  64. // ---------------------------------------------------------------------------
  65. //        Ñ Destructor
  66. // ---------------------------------------------------------------------------
  67. // Unregister with the manager
  68.  
  69. CTearOffBar::~CTearOffBar()
  70. {
  71.     CTearOffManager::GetDefaultManager()->UnregisterBar(this);
  72. }
  73.  
  74. // ---------------------------------------------------------------------------
  75. //        Ñ FinishCreateSelf
  76. // ---------------------------------------------------------------------------
  77. // Register with the manager
  78.  
  79. void CTearOffBar::FinishCreateSelf()
  80. {
  81.     CTearOffManager::GetDefaultManager()->RegisterBar(this);
  82. }
  83.  
  84. // ---------------------------------------------------------------------------
  85. //        Ñ Click
  86. // ---------------------------------------------------------------------------
  87. // Slightly modified LView::Click
  88. // We should handle clicks in the transparent pane
  89. // We need this because the PPob view that holds the buttons that we put inside
  90. // completely covers this view. Unless we make that view transparent, we'll never
  91. // get any clicks
  92.  
  93. void CTearOffBar::Click( SMouseDownEvent    &inMouseDown )
  94. {
  95.                                     // Check if a SubPane of this View
  96.                                     //   is hit
  97. // Modified code
  98. // Check if we have clicked on a 0 pane
  99.     LPane    *clickedPane = FindDeepSubPaneContaining(inMouseDown.wherePort.h,
  100.                                             inMouseDown.wherePort.v );
  101.     if (clickedPane != nil && clickedPane->GetPaneID() == fTransparentPane)
  102.     {
  103.         LPane::Click(inMouseDown);
  104.         return;
  105.     }
  106.  
  107. // LView::Click code
  108.     clickedPane = FindSubPaneHitBy(inMouseDown.wherePort.h,
  109.                                             inMouseDown.wherePort.v);
  110.                                             
  111.     if    ( clickedPane != nil )
  112.     {        //  SubPane is hit, let it respond to the Click
  113.         clickedPane->Click(inMouseDown);
  114.         
  115.     } else {                        // No SubPane hit, or maybe pane 0. Inherited function
  116.         LPane::Click(inMouseDown);    //   will process click on this View
  117.     }
  118. }
  119.  
  120. // ---------------------------------------------------------------------------
  121. //        Ñ ClickSelf
  122. // ---------------------------------------------------------------------------
  123. // Drag the outline of the bar out of the window
  124. // Roughly copied out of UDesktop::DragDeskWindow
  125.  
  126. void CTearOffBar::ClickSelf(const SMouseDownEvent    &inMouseDown)
  127. {
  128.     if (::WaitMouseUp()) {                // Continue if mouse hasn't been
  129.                                         //   released
  130.                                         
  131.         GrafPtr        savePort;            // Use ScreenPort for dragging
  132.         GetPort(&savePort);
  133.         GrafPtr        screenPort = UScreenPort::GetScreenPort();
  134.         ::SetPort(screenPort);
  135.         StColorPenState::Normalize();
  136.  
  137. // Get surrounding rectangle in global port coordinates
  138.  
  139.         Rect frame;
  140.         Point topLeft, botRight;
  141.         topLeft.h = mFrameLocation.h;
  142.         topLeft.v = mFrameLocation.v;
  143.         botRight.h = topLeft.h + mFrameSize.width;
  144.         botRight.v = topLeft.v + mFrameSize.height;
  145.         PortToGlobalPoint(topLeft);
  146.         PortToGlobalPoint(botRight);
  147.         
  148.         ::SetRect( &frame, topLeft.h, topLeft.v, botRight.h, botRight.v );
  149.         StRegion dragRgn(frame);
  150.         
  151.                                         // Let user drag a dotted outline
  152.                                         //   of the Window
  153.         Rect    dragRect = (**(GetGrayRgn())).rgnBBox;
  154.         ::InsetRect(&dragRect, 4, 4);
  155.         
  156.         Int32    dragDistance = ::DragGrayRgn(dragRgn, inMouseDown.macEvent.where,
  157.                                             &dragRect, &dragRect,
  158.                                             noConstraint, nil);
  159.         ::SetPort(savePort);
  160.         
  161.             // Check if the Window moved to a new, valid location.
  162.             // DragGrayRgn returns the constant Drag_Aborted if the
  163.             // user dragged outside the DragRect, which cancels
  164.             // the drag operation. We also check for the case where
  165.             // the drag finished at its original location (zero distance).
  166.             
  167.         Int16    horizDrag = LoWord(dragDistance);
  168.         Int16    vertDrag = HiWord(dragDistance);
  169.         
  170.         if (dragDistance == 0x80008000) return;
  171.             // 0x80008000 == Drag_Aborted from UFloatingDesktop
  172.         Boolean realDrag = horizDrag != 0 || vertDrag != 0;
  173.         if (fAllowClickDrag || realDrag)
  174.         {
  175.              
  176.                 // A valid drag occurred. horizDrag and vertDrag are
  177.                 // distances from the current location. We need to
  178.                 // get the new location for the Window in global
  179.                 // coordinates. The bounding box of the Window's
  180.                 // content region gives the current location in
  181.                 // global coordinates. Add drag distances to this
  182.                 // to get the new location. 
  183.             CTearOffManager::GetDefaultManager()->DragBar(this, 
  184.                                                     topLeft.h + horizDrag,
  185.                                                     topLeft.v + vertDrag,
  186.                                                     realDrag);
  187.         }
  188.     }
  189. }
  190.  
  191. // ---------------------------------------------------------------------------
  192. //        Ñ AddListener
  193. // ---------------------------------------------------------------------------
  194. // Tell manager that we have a listener
  195.  
  196. void CTearOffBar::AddListener(LListener    *inListener)
  197. {
  198.     LBroadcaster::AddListener(inListener);
  199.     CTearOffManager::GetDefaultManager()->RegisterListener(this, inListener);
  200. }
  201.  
  202. // ---------------------------------------------------------------------------
  203. //        Ñ ListenToMessage 
  204. // ---------------------------------------------------------------------------
  205. // Tell TearOffManager that we got the message
  206. void CTearOffBar::ListenToMessage(MessageT inMessage, void *ioParam)
  207. {
  208.     CTearOffManager::GetDefaultManager()->BarReceivedMessage(this, inMessage, ioParam);
  209. }
  210.  
  211. // ---------------------------------------------------------------------------
  212. //        Ñ ListenToMessage 
  213. // ---------------------------------------------------------------------------
  214. // Tell TearOffManager that we got the message
  215. void CTearOffBar::ActivateSelf()
  216. {
  217.     LView::ActivateSelf();
  218.     CTearOffManager::GetDefaultManager()->BarActivated(this);
  219. }
  220.  
  221. // ---------------------------------------------------------------------------
  222. //        Ñ ListenToMessage 
  223. // ---------------------------------------------------------------------------
  224. // Tell TearOffManager that we got the message
  225. void CTearOffBar::DeactivateSelf()
  226. {
  227.     LView::DeactivateSelf();
  228.     CTearOffManager::GetDefaultManager()->BarDeactivated(this);
  229. }
  230.  
  231. // ---------------------------------------------------------------------------
  232. //        Ñ HidePalette 
  233. // ---------------------------------------------------------------------------
  234. // Delete all the subpanes.
  235. // Manager will broadcast a message msg_FloatPalleteRemoved to your listener
  236. void CTearOffBar::HidePalette()
  237. {
  238.     DeleteAllSubPanes();
  239.     if (fAutoResize)
  240.         ResizeFrameTo(0,0,TRUE);
  241.     else
  242.         Refresh();
  243.     fShown = false;
  244. }
  245.  
  246. // ---------------------------------------------------------------------------
  247. //        Ñ ShowPalette 
  248. // ---------------------------------------------------------------------------
  249. // Reads in the subview from PPob.
  250. // Position the view properly
  251.  
  252. void CTearOffBar::ShowPalette()
  253. {
  254.     if (fShown)
  255.         return;
  256.     // setup commander (window), superview(this), and listener(this)
  257.     
  258.     SetDefaultView(this);
  259.     LWindow * commander = LWindow::FetchWindowObject(GetMacPort());
  260.     SignalIfNot_( commander );
  261.  
  262.     LView * view = UReanimator::CreateView(fInPlaceSubpaneID, this, commander);
  263.     
  264.     SignalIfNot_ ( view );    // We need that pane ID
  265.  
  266.     view->FinishCreate();
  267.     fTransparentPane = view->GetPaneID();
  268.     UReanimator::LinkListenerToControls(this, this, fInPlaceSubpaneID);
  269.     UReanimator::LinkListenerToControls(CTearOffManager::GetDefaultManager(),
  270.                                         this, fInPlaceSubpaneID);
  271.  
  272.     if (fAutoResize)
  273.         ResizeFrameTo(fOriginalFrameSize.width, fOriginalFrameSize.height, TRUE);
  274. #ifdef DEBUG
  275.     if (fAutoResize)
  276.     {
  277.         SDimension16 s;
  278.         view->GetFrameSize(s);
  279.         // The container and the loaded view should be the same width/height???
  280.         SignalIf_(s.width != fOriginalFrameSize.width);
  281.         SignalIf_(s.height != fOriginalFrameSize.height);
  282.     }    
  283. #endif
  284.     fShown = true;
  285. }
  286.  
  287. #pragma mark -
  288. #pragma mark CTearOffWindow
  289. #pragma mark -
  290. /************************************************************************
  291.  * class CTearOffWindow
  292.  *
  293.  * just registers/unregisters itself with the 
  294.  * You cannot subclass this class, because CTearOffManager creates all
  295.  * palettes out of a single PPob.
  296.  ************************************************************************/
  297. #define SAVE_POSITION 1
  298.  
  299. #if SAVE_POSITION
  300. #include "CSaveWindowStatus.h"
  301. #endif // SAVE_POSITION
  302.  
  303. //======================================
  304. class CTearOffWindow
  305.         : public LWindow,
  306.             public LListener
  307.             , public CToolbarModeChangeListener
  308. #if SAVE_POSITION
  309.         , public CSaveWindowStatus
  310. #endif // SAVE_POSITION
  311. //======================================
  312. {
  313. private:
  314.     typedef LWindow Inherited;
  315.     friend class CTearOffManager;
  316. public:
  317.     enum { class_ID = 'DRFW' };
  318.         
  319. // Constructors
  320.  
  321.                             CTearOffWindow(LStream* inStream);
  322.  
  323.     virtual                ~CTearOffWindow();
  324.  
  325. // Events
  326.     virtual void        ListenToMessage(MessageT inMessage, void *ioParam);
  327.  
  328.     virtual void HandleModeChange(Int8 inNewMode);
  329.     virtual void DoSetZoom( Boolean );
  330.     virtual void AdjustWindowSizeBy( SDimension16& size_change );
  331.  
  332. #if SAVE_POSITION
  333. private:
  334.     virtual ResIDT        GetStatusResID(void) const { return FLOAT_ID; }
  335.     virtual UInt16        GetValidStatusVersion(void) const { return 0x0111; }
  336.     virtual void        FinishCreateSelf();
  337.     virtual void        AttemptClose();
  338.     virtual void        DoClose();
  339. #endif // SAVE_POSITION
  340. private:
  341.     UInt8                fVisibility;    // Inherited from the bar
  342. };
  343.  
  344. //-----------------------------------
  345. CTearOffWindow::CTearOffWindow(LStream* inStream)
  346. //-----------------------------------
  347. :    LWindow(inStream)
  348. ,    CSaveWindowStatus(this)
  349. {
  350.     PREF_SetBoolPref("taskbar.mac.is_open", true);
  351. }
  352.  
  353. //-----------------------------------
  354. CTearOffWindow::~CTearOffWindow()
  355. //-----------------------------------
  356. {
  357.     // Notify the manager
  358.     CTearOffManager::GetDefaultManager()->UnregisterWindow(this);
  359.  
  360.         // YIKES! Save this preference if the app _isn't_ quitting.  What an ugly hack!
  361.     if ( CFrontApp::sApplication->GetState() == programState_ProcessingEvents )
  362.         PREF_SetBoolPref("taskbar.mac.is_open", false);
  363. }
  364.  
  365. #if SAVE_POSITION
  366.  
  367. //-----------------------------------
  368. void CTearOffWindow::FinishCreateSelf()
  369. //-----------------------------------
  370. {
  371.     Inherited::FinishCreateSelf();
  372.     CSaveWindowStatus::FinishCreateWindow();
  373.     
  374.     SDimension16 zero_zero = {0,0};
  375.     AdjustWindowSizeBy(zero_zero);
  376. }
  377.  
  378. //-----------------------------------
  379. void CTearOffWindow::AttemptClose()
  380. //-----------------------------------
  381. {
  382.     AttemptCloseWindow();
  383.     Inherited::AttemptClose();
  384. }
  385.  
  386. //-----------------------------------
  387. void CTearOffWindow::DoClose()
  388. //-----------------------------------
  389. {
  390.     AttemptCloseWindow();
  391.     Inherited::DoClose();
  392. }
  393.  
  394. #endif // SAVE_POSITION
  395.  
  396.  
  397. void CTearOffWindow::HandleModeChange( Int8 inNewMode )
  398.     {
  399.         SDimension16    size_change={ 0, 0 };
  400.         if ( CToolbarButtonContainer* container_ptr = dynamic_cast<CToolbarButtonContainer*>(FindPaneByID('TBPv')) )
  401.             container_ptr->HandleModeChange(inNewMode, size_change);
  402.         AdjustWindowSizeBy(size_change);
  403.     }
  404.  
  405.  
  406. void CTearOffWindow::DoSetZoom( Boolean )
  407.     {
  408.         SDimension16    size_change={ 0, 0 };
  409.         if ( CToolbarPatternBevelView* container_ptr = dynamic_cast<CToolbarPatternBevelView*>(FindPaneByID('TBPv')) )
  410.             container_ptr->RotateArrangement(size_change);
  411.         AdjustWindowSizeBy(size_change);
  412.  
  413.         SDimension16 frameSize;
  414.         GetFrameSize(frameSize);
  415.         PREF_SetBoolPref("taskbar.mac.is_vertical", XP_Bool(frameSize.height > frameSize.width));
  416.     }
  417.  
  418. void CTearOffWindow::AdjustWindowSizeBy( SDimension16& size_change )
  419.     {
  420.             /*
  421.                 Always adjust the size (even if size_change is {0,0}) because the caller
  422.                 might be trying to ensure that the window is pinned to the screen.
  423.             */
  424.         Rect frame_rect;
  425.         CalcPortFrameRect(frame_rect);
  426.         PortToGlobalPoint(topLeft(frame_rect));
  427.         PortToGlobalPoint(botRight(frame_rect));
  428.  
  429.         frame_rect.right += size_change.width;
  430.         frame_rect.bottom += size_change.height;
  431.  
  432.         VerifyWindowBounds(mWindowSelf, &frame_rect);
  433.  
  434.         DoSetBounds(frame_rect);
  435.     }
  436.  
  437. // ---------------------------------------------------------------------------
  438. //        Ñ CTearOffWindow destructor
  439. // ---------------------------------------------------------------------------
  440. // Pass on to the manager
  441. void CTearOffWindow::ListenToMessage(MessageT inMessage, void *ioParam)
  442. {
  443.     if ( inMessage == CToolbarModeManager::msg_ToolbarModeChange )
  444.         HandleModeChange((Int8)ioParam);
  445.     else
  446.         CTearOffManager::GetDefaultManager()->WindowReceivedMessage(this, inMessage, ioParam);
  447. }
  448.  
  449. /*****************************************************************************
  450.  * class CTearOffManager
  451.  *****************************************************************************/
  452. #pragma mark -
  453. #pragma mark CTearOffManager
  454. #pragma mark -
  455. CTearOffManager *  CTearOffManager::sDefaultFloatManager = NULL;
  456.  
  457. #pragma mark struct ButtonBarRecord
  458. // holds information about a single button bar, stored in fPaletteBars list
  459. struct ButtonBarRecord
  460. {
  461.     ResIDT                fID;    // ResID of the PPob loaded into the button bar.
  462.     ResIDT                fWindowID;    // ResID of the PPob loaded into the floating window.
  463.     CTearOffBar *    fBar;    // Pointer to the bar
  464.     LListener *         fListener;    // The listener for this bar
  465.         
  466.     ButtonBarRecord()
  467.     {
  468.         fID = -1;
  469.         fWindowID = -1;
  470.         fBar = NULL;
  471.         fListener = NULL;
  472.     }
  473.     
  474.     ButtonBarRecord(ResIDT id, ResIDT wID, CTearOffBar * bar, LListener * listener)
  475.     {
  476.         fID = id;
  477.         fWindowID = wID;
  478.         fBar = bar;
  479.         fListener = listener;
  480.     }
  481. };
  482.  
  483. /****************************************************************************
  484.  * struct FloatWindowRecord
  485.  * used to keep a list of loaded windows
  486.  ****************************************************************************/
  487. #pragma mark struct FloatWindowRecord
  488. struct FloatWindowRecord
  489. {
  490.     CTearOffWindow * fWindow;
  491.     ResIDT                fID;        // Res ID of the PPob to be loaeded
  492.     CTearOffBar * fActiveBar;
  493.  
  494.     FloatWindowRecord(CTearOffWindow * window, ResIDT resID, CTearOffBar * activeBar = NULL)
  495.     {
  496.         fWindow = window;
  497.         fID = resID;
  498.         fActiveBar = activeBar;
  499.     }
  500.  
  501. };
  502.  
  503. // ---------------------------------------------------------------------------
  504. //        Ñ Compare the window records
  505. // ---------------------------------------------------------------------------
  506. // Wildcards can be used for fID and fWindow fields
  507. // fListener field is not used.
  508.  
  509. #define WILDCARD -1
  510.  
  511. Int32 CTearOffManager::CPaletteWindowComparator::Compare(const void*        inItemOne,
  512.                                     const void*        inItemTwo,
  513.                                     Uint32            inSizeOne,
  514.                                     Uint32            inSizeTwo) const
  515. {
  516. #pragma unused (inSizeOne, inSizeTwo)    // Cause we know what the items are
  517.  
  518.     FloatWindowRecord * item1 = (FloatWindowRecord *)inItemOne;
  519.     FloatWindowRecord * item2 = (FloatWindowRecord *)inItemTwo;
  520.  
  521.     if ( item1->fID != item2->fID &&    // Different floaters
  522.          (item1->fID != WILDCARD) &&
  523.          (item2->fID != WILDCARD))    
  524.         return (item1->fWindow - item2->fWindow);
  525.     else                            // Same floaters
  526.         if ( item1->fWindow == item2->fWindow ||
  527.             ( item1->fWindow == (void*)WILDCARD ) ||
  528.             ( item2->fWindow == (void*)WILDCARD ) )
  529.             return 0;
  530.         else
  531.             return item1->fWindow - item2->fWindow;
  532. }
  533.  
  534. // ---------------------------------------------------------------------------
  535. //        Ñ Compare the bars
  536. // ---------------------------------------------------------------------------
  537. // Wildcards can be used for fID and fBar fields
  538. // fListener field is not used.
  539.  
  540. Int32 CTearOffManager::CPaletteBarComparator::Compare(const void*        inItemOne,
  541.                                     const void*        inItemTwo,
  542.                                     Uint32            inSizeOne,
  543.                                     Uint32            inSizeTwo) const
  544. {
  545. #pragma unused (inSizeOne, inSizeTwo)    // Cause we know what the items are
  546.  
  547.     ButtonBarRecord * item1 = (ButtonBarRecord *)inItemOne;
  548.     ButtonBarRecord * item2 = (ButtonBarRecord *)inItemTwo;
  549.  
  550.  
  551.     if ( item1->fID != item2->fID &&    // Different IDs
  552.          (item1->fID != WILDCARD) &&
  553.          (item2->fID != WILDCARD) )    
  554.         return ( item1->fBar - item2->fBar );
  555.     if (item1->fWindowID != item2->fWindowID &&    // Different floaters
  556.          (item1->fWindowID != WILDCARD) &&
  557.          (item2->fWindowID != WILDCARD) )
  558.         return ( item1->fBar - item2->fBar );
  559.     else                            // Same floaters
  560.         if ( item1->fBar == item2->fBar ||
  561.             ( item1->fBar == (void*)WILDCARD ) ||
  562.             ( item2->fBar == (void*)WILDCARD ) )
  563.             return 0;
  564.         else
  565.             return item1->fBar - item2->fBar;
  566.     return 0;    // Kill the warning
  567. }
  568.  
  569. // ---------------------------------------------------------------------------
  570. //        Ñ CTearOffManager Constructor 
  571. // ---------------------------------------------------------------------------
  572. // sets the default manager
  573.  
  574. CTearOffManager::CTearOffManager(LCommander * defaultCommander)
  575. {
  576.     sDefaultFloatManager = this;
  577.     
  578.     // These lists cannot be sorted, because sometimes we do wildcard lookups
  579.     // If you want to sort them, implement CompareKey better
  580.     fPaletteBars = new LArray( sizeof (ButtonBarRecord), &fBarCompare, false );
  581.     fPaletteWindows = new LArray( sizeof (FloatWindowRecord), &fWindowCompare, false );
  582.  
  583.     fDefaultCommander = defaultCommander;
  584. }
  585.  
  586. // ---------------------------------------------------------------------------
  587. //        Ñ CTearOffManager destructor -- never called, here for completeness
  588. // ---------------------------------------------------------------------------
  589. // clean up
  590. CTearOffManager::~CTearOffManager()
  591. {
  592.     delete fPaletteBars;
  593.     delete fPaletteWindows;
  594. }
  595.  
  596.  
  597. void CTearOffManager::ListenToMessage(MessageT inMessage, void *ioParam)
  598. {
  599.     BroadcastMessage(inMessage, ioParam);
  600. }
  601.  
  602.  
  603. // ---------------------------------------------------------------------------
  604. //        Ñ RegisterBar 
  605. // ---------------------------------------------------------------------------
  606. // Insert the bar in the bar list. Hide or show it, depending on the window
  607.  
  608. void CTearOffManager::RegisterBar(CTearOffBar * inBar)
  609. {
  610.     // Insert it into the list
  611.     ButtonBarRecord barRec( inBar->fInPlaceSubpaneID, inBar->fFloatingSubpaneID, inBar, NULL);
  612.     fPaletteBars->InsertItemsAt(1, fPaletteBars->GetCount(), &barRec, sizeof( barRec ) );
  613.     
  614.     // Decide whether to hide or show the bar
  615.  
  616.     FloatWindowRecord fr( (CTearOffWindow *)WILDCARD, inBar->fFloatingSubpaneID );
  617.     ArrayIndexT where = fPaletteWindows->FetchIndexOfKey( &fr );
  618.     if ( where != LArray::index_Bad )
  619.         inBar->HidePalette();
  620.     else
  621.         inBar->ShowPalette();
  622. }
  623.  
  624. // ---------------------------------------------------------------------------
  625. //        Ñ UnregisterBar 
  626. // ---------------------------------------------------------------------------
  627. // Remove the bar from the bar list
  628. // If there are any "left-over" floaters, remove them
  629.  
  630. void CTearOffManager::UnregisterBar(CTearOffBar * inBar)
  631. {
  632.     ButtonBarRecord bar( WILDCARD, WILDCARD, inBar, NULL);
  633.     ArrayIndexT where = fPaletteBars->FetchIndexOfKey(&bar);
  634.     if ( where != LArray::index_Bad )
  635.         fPaletteBars->RemoveItemsAt( 1, where );
  636.     else
  637.         SignalCStr_("Unregistering a bar that was never registered?");
  638.  
  639. // If there are no other bars with the same ID,
  640. // remove the floater window (floater might not exist)
  641.  
  642.     ButtonBarRecord brotherBar( inBar->fInPlaceSubpaneID, inBar->fFloatingSubpaneID,
  643.                                 (CTearOffBar *)WILDCARD, NULL );
  644.     
  645.     where = fPaletteBars->FetchIndexOfKey(&brotherBar);
  646.     if ( where == LArray::index_Bad )
  647.     // Remove the floaters with this ID
  648.     {
  649.         FloatWindowRecord fw( (CTearOffWindow*) WILDCARD, inBar->fFloatingSubpaneID );
  650.         ArrayIndexT where = fPaletteWindows->FetchIndexOfKey( &fw );
  651.         if ( where != LArray::index_Bad )
  652.         {
  653.             fPaletteWindows->FetchItemAt( where, &fw );
  654.             if (fw.fWindow->fVisibility != 0)
  655.                 delete fw.fWindow;    // this will automatically remove it from the list
  656.         }
  657.     }
  658. }
  659.     
  660. // ---------------------------------------------------------------------------
  661. //        Ñ RegisterListener 
  662. // ---------------------------------------------------------------------------
  663. // Set the listener
  664. // Broadcast the palette message to the window, depending on where the palette is
  665.  
  666. void CTearOffManager::RegisterListener(CTearOffBar * inBar, 
  667.                                             LListener * listener)
  668. {
  669.     ButtonBarRecord bar( WILDCARD, WILDCARD, inBar, listener );
  670.     ArrayIndexT where = fPaletteBars->FetchIndexOfKey(&bar);
  671.     if (where != LArray::index_Bad)
  672.     {
  673.     // assign the listener
  674.         fPaletteBars->FetchItemAt( where, &bar );
  675.         bar.fListener = listener;
  676.         fPaletteBars->AssignItemsAt( 1, where , &bar );
  677.     
  678.     // broadcast the palette message to the listener
  679.         FloatWindowRecord fr( (CTearOffWindow *)WILDCARD, inBar->fFloatingSubpaneID );
  680.         ArrayIndexT where = fPaletteWindows->FetchIndexOfKey( &fr );
  681.         
  682.         if ( where != LArray::index_Bad )
  683.         {
  684.         // We have a window to register
  685.             fPaletteWindows->FetchItemAt( where, &fr );
  686.             SetBarsView( inBar, fr.fWindow );
  687.         }
  688.         else
  689.         // The bar holds the palette
  690.         {
  691.             SetBarsView( inBar, inBar );
  692.         }
  693.     }
  694.     else
  695.         SignalCStr_("Bar never registered?");
  696. }
  697.     
  698. // ---------------------------------------------------------------------------
  699. //        Ñ BarReceivedMessage 
  700. // ---------------------------------------------------------------------------
  701. // Relay the message to its listeners
  702.  
  703. void CTearOffManager::BarReceivedMessage(CTearOffBar * inBar,
  704.                                             MessageT inMessage,
  705.                                              void *ioParam)
  706. {
  707.     ButtonBarRecord bar( WILDCARD, WILDCARD, inBar, NULL );
  708.     ArrayIndexT where = fPaletteBars->FetchIndexOfKey(&bar);
  709.     
  710.     if ( where != LArray::index_Bad )
  711.     {
  712.         fPaletteBars->FetchItemAt( where, &bar );
  713. //        SignalIfNot_(bar.fListener);
  714.         if (bar.fListener)
  715.             bar.fListener->ListenToMessage( inMessage, ioParam );
  716.     }
  717.     else
  718.         SignalCStr_("Bar never registered?");
  719. }
  720.  
  721. // ---------------------------------------------------------------------------
  722. //        Ñ DragBar 
  723. // ---------------------------------------------------------------------------
  724. // Assert that the window exists
  725. // move it to the new location
  726.  
  727. void CTearOffManager::DragBar( CTearOffBar * inBar,
  728.                                 Int16 inH,
  729.                                 Int16 inV,
  730.                                 Boolean usePosition )
  731. {
  732.     try
  733.     {
  734.         CTearOffWindow * win = AssertBarWindowExists(inBar);
  735.  
  736. #if SAVE_POSITION
  737.     if (usePosition) {
  738. #endif
  739.         Point topLeft;
  740.         topLeft.h = inH;
  741.         topLeft.v = inV;
  742.         win->DoSetPosition(topLeft);
  743. #if SAVE_POSITION
  744.         }
  745. #endif
  746.         win->Show();
  747.         
  748.         SetBarsView( inBar, win );
  749.     }
  750.     catch(OSErr inErr)
  751.     {
  752.         SignalCStr_("Did you include UTearOffPalette.r in your project?");
  753.         // No window, button bar stays where it was
  754.     }
  755. }
  756.  
  757. // ---------------------------------------------------------------------------
  758. //        Ñ BarActivated 
  759. // ---------------------------------------------------------------------------
  760. // Upon activation:
  761. // Tell its float windowGets the floater window for the bar
  762. // Tells listener what the current palette is
  763. // 
  764. void CTearOffManager::BarActivated( CTearOffBar * inBar)
  765. {
  766. // Find the floater window
  767.     FloatWindowRecord fw( (CTearOffWindow *) WILDCARD, inBar->fFloatingSubpaneID );
  768.     ArrayIndexT where = fPaletteWindows->FetchIndexOfKey( &fw );
  769.  
  770. // If we have a window, make this bar the active one
  771.     if ( where != LArray::index_Bad )
  772.     {
  773.         fPaletteWindows->FetchItemAt( where, &fw );
  774.         if ( fw.fActiveBar != inBar )
  775.         {
  776.             if ( fw.fActiveBar == NULL )    // If there was no view, we need to enable us
  777.             {
  778.                 LPane * view;
  779.                 LArrayIterator iter( fw.fWindow->GetSubPanes());
  780.                 if ( iter.Next(&view) )    // We have disabled this on suspends
  781.                     view->Enable();
  782.             }
  783.             
  784.             fw.fActiveBar = inBar;
  785.             fPaletteWindows->AssignItemsAt( 1, where , &fw );
  786.             fw.fWindow->Show();
  787.             
  788.  
  789.             SetBarsView(inBar, fw.fWindow);
  790.             
  791.         }
  792.     }
  793. }
  794.  
  795. // ---------------------------------------------------------------------------
  796. //        Ñ BarDeactivated 
  797. // ---------------------------------------------------------------------------
  798. // Upon deactivation
  799. // If we have a floating window, make it inactive and tell listener about it
  800.  
  801. void CTearOffManager::BarDeactivated( CTearOffBar * inBar)
  802. {
  803.     FloatWindowRecord fw( (CTearOffWindow *) WILDCARD, inBar->fFloatingSubpaneID );
  804.     ArrayIndexT where = fPaletteWindows->FetchIndexOfKey( &fw );
  805.  
  806.     if ( where != LArray::index_Bad )
  807.     {
  808.         fPaletteWindows->FetchItemAt( where, &fw );
  809.         if ( fw.fActiveBar == inBar )
  810.         {
  811.             if ( fw.fWindow->fVisibility == 2 )
  812.                 fw.fWindow->Hide();
  813.             else
  814.             {
  815.                 if (inBar->DisablePaletteWindow())
  816.                 {
  817.                     // Disable all the subpanes of our main subpane
  818.                     // Do not disable the main pane, because no one enables it
  819.                     LPane * view;
  820.                     LArrayIterator iter( fw.fWindow->GetSubPanes());
  821.                     if ( iter.Next(&view) )
  822.                         view->Disable();
  823.                 }
  824.             }
  825.             fw.fActiveBar = NULL;
  826.             fPaletteWindows->AssignItemsAt( 1, where , &fw );
  827.             RemoveBarsView(inBar, inBar->fTransparentPane);
  828.         }
  829.     }
  830. }
  831.  
  832. // ---------------------------------------------------------------------------
  833. //        Ñ SetBarsView 
  834. // ---------------------------------------------------------------------------
  835. // Tell listener what its palette view is
  836. // InView is either FBar, or FWindow. In either case, the palette is the first subview
  837.  
  838. void CTearOffManager::SetBarsView( CTearOffBar * inBar,
  839.                                         LView * inView)
  840. {
  841.     SignalIfNot_( inView );
  842.  
  843.     // Get the bar record
  844.     ButtonBarRecord br( WILDCARD, WILDCARD, inBar, (LListener*) WILDCARD );
  845.     ArrayIndexT where = fPaletteBars->FetchIndexOfKey( &br );
  846.  
  847.     if ( where != LArray::index_Bad )
  848.     {
  849.         fPaletteBars->FetchItemAt( where, &br );
  850.         if ( br.fListener )
  851.         {
  852.             // Palette is the first subview
  853.             LView * topPaletteView;
  854.             LArrayIterator iter( inView->GetSubPanes());
  855.             if ( iter.Next(&topPaletteView) )
  856.                 br.fListener->ListenToMessage( msg_SetTearOffPalette, topPaletteView );
  857.         }
  858.     }
  859.     else
  860.         SignalCStr_("Where is the bar?");            
  861. }
  862.  
  863. // ---------------------------------------------------------------------------
  864. //        Ñ RemoveBarsView 
  865. // ---------------------------------------------------------------------------
  866. // Similar to SetBarsView. Must get the top pane ID from somewhere 
  867.  
  868. void CTearOffManager::RemoveBarsView( CTearOffBar * inBar, PaneIDT inViewID)
  869. {
  870.     ButtonBarRecord br( WILDCARD, WILDCARD, inBar, (LListener*) WILDCARD );
  871.     ArrayIndexT where = fPaletteBars->FetchIndexOfKey( &br );
  872.  
  873.     if ( where != LArray::index_Bad )
  874.     {
  875.         fPaletteBars->FetchItemAt( where, &br );
  876.         if ( br.fListener )
  877.             br.fListener->ListenToMessage( msg_RemoveTearOffPalette, (void*) inViewID );
  878.     }
  879.     else
  880.         SignalCStr_("Where is the bar?");        
  881. }
  882.  
  883. // ---------------------------------------------------------------------------
  884. //        Ñ AssertBarWindowExists 
  885. // ---------------------------------------------------------------------------
  886. // Create the window if it does not exist
  887.  
  888. CTearOffWindow * CTearOffManager::AssertBarWindowExists(CTearOffBar * inBar)
  889. {
  890.     return AssertBarWindowExists(
  891.         inBar->fFloatingSubpaneID,
  892.         inBar->IsFloaterOnSide(),
  893.         inBar->fVisibility,
  894.         inBar->fTitle
  895.         );
  896. }
  897.  
  898. // ---------------------------------------------------------------------------
  899. //        Ñ AssertBarWindowExists 
  900. // ---------------------------------------------------------------------------
  901. // Create the window if it does not exist
  902.  
  903. CTearOffWindow * CTearOffManager::AssertBarWindowExists(ResIDT inWinID,
  904.                                                         Boolean inSideways,
  905.                                                         UInt8 visibility,
  906.                                                         Str255 &title)
  907. {
  908.     FloatWindowRecord fw( (CTearOffWindow *) WILDCARD, inWinID );
  909.     ArrayIndexT where = fPaletteWindows->FetchIndexOfKey( &fw );
  910.     CTearOffWindow * newWindow = nil;
  911.     if (where == LArray::index_Bad)
  912.     {
  913.     // Create a new window, load the palette into it
  914.         ResIDT windowResID = inSideways ? SIDE_FLOAT_ID : FLOAT_ID;
  915.  
  916.         newWindow = (CTearOffWindow *) LWindow::CreateWindow(windowResID, fDefaultCommander);
  917.  
  918.         ThrowIfNil_(newWindow);
  919.         newWindow->fVisibility = visibility;
  920.  
  921.         LView * view = UReanimator::CreateView(inWinID, newWindow, newWindow);
  922.         ThrowIfNil_( view );
  923.         view->FinishCreate();
  924.  
  925.         UReanimator::LinkListenerToControls(CTearOffManager::GetDefaultManager(),
  926.                                             view, inWinID);
  927.     // Resize the window
  928.         Point corner = {0,0};
  929. #if SAVE_POSITION
  930.         newWindow->PortToGlobalPoint(corner);
  931. #endif        
  932.         SDimension16 viewSize;
  933.         Rect winBounds;
  934.         view->GetFrameSize(viewSize);
  935.         ::SetRect(&winBounds,
  936.                 corner.h, corner.v,
  937.                 corner.h + viewSize.width, corner.v + viewSize.height);
  938.         newWindow->DoSetBounds( winBounds );
  939.         newWindow->SetDescriptor(title);
  940.  
  941.         SBooleanRect boundToSuperview={ true, true, true, true };
  942.         view->SetFrameBinding(boundToSuperview);
  943.  
  944.         Int32 toolbarStyle;
  945.         if ( (PREF_GetIntPref("browser.chrome.toolbar_style", &toolbarStyle) == PREF_NOERROR)
  946.             && (toolbarStyle != CToolbarModeManager::defaultToolbarMode) )
  947.             {
  948.                 ((CTearOffWindow*)newWindow)->HandleModeChange(toolbarStyle);
  949.             }
  950.  
  951.         XP_Bool is_vertical = true;
  952.         if ( (PREF_GetBoolPref("taskbar.mac.is_vertical", &is_vertical) == PREF_NOERROR)
  953.             && !is_vertical )
  954.             {
  955.                 ((CTearOffWindow*)newWindow)->DoSetZoom(Boolean());
  956.             }
  957.  
  958.     // Add the record to the list of managed floaters
  959.         FloatWindowRecord fw(newWindow, inWinID, NULL);
  960.         fPaletteWindows->InsertItemsAt( 1, fPaletteWindows->GetCount(), &fw, sizeof (fw) );
  961.  
  962.     // Hide the bars button palletes
  963.         LArrayIterator iter(*fPaletteBars);
  964.         ButtonBarRecord bar;
  965.         while ( iter.Next(&bar) )
  966.             if (bar.fWindowID == fw.fID)
  967.             {
  968.                 bar.fBar->HidePalette();
  969.                 bar.fBar->fTransparentPane = view->GetPaneID();
  970.                 RemoveBarsView( bar.fBar, bar.fBar->fTransparentPane );
  971.             }
  972.     // Link up the new controls
  973.         UReanimator::LinkListenerToControls( newWindow, newWindow, fw.fID );
  974.     }
  975.     else
  976.     {
  977.         fPaletteWindows->FetchItemAt( where, &fw );
  978.         return fw.fWindow;
  979.     }
  980.     return newWindow;
  981. } // CTearOffManager::AssertBarWindowExists
  982.  
  983. // ---------------------------------------------------------------------------
  984. //        Ñ UnregisterWindow 
  985. // ---------------------------------------------------------------------------
  986. // Remove the window from the list
  987. // Show all the floaters
  988.  
  989. void CTearOffManager::UnregisterWindow(CTearOffWindow * window)
  990. {
  991.     // Remove the window from the list
  992.     FloatWindowRecord fw( window, WILDCARD );
  993.     ArrayIndexT where = fPaletteWindows->FetchIndexOfKey( &fw );
  994.  
  995.     if ( where != LArray::index_Bad )
  996.     {
  997.         fPaletteWindows->FetchItemAt( where, &fw );
  998.         fPaletteWindows->RemoveItemsAt( 1, where );
  999.     }
  1000.     else
  1001.         SignalCStr_("Removal of unregistered window?");
  1002.     
  1003.     // Tell all button bars to show themselves
  1004.     
  1005.     LArrayIterator iter(*fPaletteBars);
  1006.     ButtonBarRecord bar;
  1007.     while ( iter.Next(&bar) )
  1008.         if (bar.fWindowID == fw.fID)
  1009.             {
  1010.                 bar.fBar->ShowPalette();
  1011.                 SetBarsView(bar.fBar, bar.fBar);
  1012.             }
  1013. }
  1014.  
  1015. // ---------------------------------------------------------------------------
  1016. //        Ñ CloseFloatingWindow 
  1017. // ---------------------------------------------------------------------------
  1018. // Closes the Floating Window
  1019.  
  1020. void CTearOffManager::CloseFloatingWindow(ResIDT inWinID)
  1021. {
  1022.     // find the window in the list
  1023.     FloatWindowRecord fw((CTearOffWindow *)WILDCARD, inWinID, (CTearOffBar *)WILDCARD );
  1024.     ArrayIndexT where = fPaletteWindows->FetchIndexOfKey( &fw );
  1025.  
  1026.     if ( where != LArray::index_Bad )
  1027.     {
  1028.         fPaletteWindows->FetchItemAt( where, &fw );
  1029.         fw.fWindow->ProcessCommand(cmd_Close);
  1030.     }
  1031.     else
  1032.     {
  1033.         SignalCStr_("close of unregistered window?");
  1034.     }
  1035. }
  1036.  
  1037. // ---------------------------------------------------------------------------
  1038. //        Ñ OpenFloatingWindow 
  1039. // ---------------------------------------------------------------------------
  1040. // Opens the Floating Window
  1041.  
  1042. void CTearOffManager::OpenFloatingWindow(    ResIDT inWinID,
  1043.                                             Point inTopLeft,
  1044.                                             Boolean inSideways,
  1045.                                             UInt8 visibility,
  1046.                                             Str255 &title)
  1047. {
  1048.     // find the window in the list
  1049.     FloatWindowRecord fw((CTearOffWindow *)WILDCARD, inWinID, (CTearOffBar *)WILDCARD );
  1050.     ArrayIndexT where = fPaletteWindows->FetchIndexOfKey( &fw );
  1051.  
  1052.     if (LArray::index_Bad == where)
  1053.     {
  1054.         try
  1055.         {
  1056.             CTearOffWindow * win = AssertBarWindowExists(inWinID, inSideways, visibility, title);
  1057.  
  1058. #if !SAVE_POSITION
  1059.             win->DoSetPosition(inTopLeft);
  1060. #endif
  1061.             win->Show();
  1062.         }
  1063.         catch(OSErr inErr)
  1064.         {
  1065.             SignalCStr_("Did you include UTearOffPalette.r in your project?");
  1066.             // No window, button bar stays where it was
  1067.         }
  1068.     }
  1069.     else
  1070.     {
  1071.         SignalCStr_("open of open window?");
  1072.     }
  1073. }
  1074.  
  1075.  
  1076. // ---------------------------------------------------------------------------
  1077. //        Ñ IsFloatingWindow 
  1078. // ---------------------------------------------------------------------------
  1079. // Closes the Floating Window
  1080.  
  1081. Boolean CTearOffManager::IsFloatingWindow(ResIDT inWinID)
  1082. {
  1083.     // find the window in the list
  1084.     FloatWindowRecord fw((CTearOffWindow *)WILDCARD, inWinID, (CTearOffBar *)WILDCARD );
  1085.     ArrayIndexT where = fPaletteWindows->FetchIndexOfKey( &fw );
  1086.  
  1087.     return where != LArray::index_Bad;
  1088. }
  1089.  
  1090. // ---------------------------------------------------------------------------
  1091. //        Ñ WindowReceivedMessage 
  1092. // ---------------------------------------------------------------------------
  1093. // Rebroadcast the message to the listener of the currently active bar
  1094. void CTearOffManager::WindowReceivedMessage(CTearOffWindow * inWin,
  1095.                                             MessageT inMessage,
  1096.                                              void *ioParam)
  1097. {
  1098.     // Get the window record
  1099.     FloatWindowRecord fw( inWin, WILDCARD );
  1100.     ArrayIndexT where = fPaletteWindows->FetchIndexOfKey( &fw );
  1101.  
  1102.     if ( where != LArray::index_Bad )
  1103.     {
  1104.         fPaletteWindows->FetchItemAt( where, &fw );
  1105.         
  1106.         // If there is an active bar attached to this window
  1107.         // rebroadcast the message to its listener
  1108.  
  1109.         if (fw.fActiveBar)
  1110.         {
  1111.             ButtonBarRecord bar( WILDCARD, WILDCARD, fw.fActiveBar , NULL );
  1112.             where = fPaletteBars->FetchIndexOfKey(&bar);
  1113.             if ( where != LArray::index_Bad )
  1114.             {
  1115.                 fPaletteBars->FetchItemAt( where, &bar );
  1116.                 if ( bar.fListener != NULL )
  1117.                     bar.fListener->ListenToMessage( inMessage, ioParam );
  1118.             }
  1119.         }
  1120.         
  1121.     }
  1122.     else
  1123.         SignalCStr_("Message from a window we do not know about?");
  1124. }
  1125.  
  1126. #pragma mark -
  1127. // ---------------------------------------------------------------------------
  1128. //        Ñ InitUTearOffPalette [static]
  1129. // ---------------------------------------------------------------------------
  1130. // Registers classes, creates a single float manager
  1131. void InitUTearOffPalette(LCommander * defCommander)
  1132. {
  1133.     RegisterClass_( CTearOffBar);
  1134.     RegisterClass_( CTearOffWindow);
  1135.     new CTearOffManager(defCommander);
  1136. }
  1137.  
  1138.