Back to index

lightning-sunbird  0.9+nobinonly
TopLevelFrame.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is mozilla.org code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1998
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either of the GNU General Public License Version 2 or later (the "GPL"),
00025  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 /*
00038        TopLevelFrame.cpp
00039        
00040        An MRJFrame sub-class that manages the behavior of a top-level window
00041        running inside the Communicator.
00042        
00043        by Patrick C. Beard.
00044  */
00045 
00046 #include <Controls.h>
00047 #include <Events.h>
00048 
00049 #include "TopLevelFrame.h"
00050 #include "LocalPort.h"
00051 
00052 #include "nsIPluginManager2.h"
00053 #include "nsIEventHandler.h"
00054 
00055 #if !defined(MRJPLUGIN_4X)
00056 #define USE_ALT_WINDOW_HANDLING
00057 #endif
00058 
00059 #ifdef USE_ALT_WINDOW_HANDLING
00060 #include "AltWindowHandling.h"
00061 #endif
00062 
00063 #include "nsIEventHandler.h"
00064 #include "AltWindowHandling.h"
00065 
00066 extern nsIPluginManager2* thePluginManager2;
00067 
00068 static void UnsetPort(GrafPtr port);
00069 static short getModifiers();
00070 
00071 TopLevelFrame::TopLevelFrame(nsIEventHandler* handler, JMFrameRef frameRef, JMFrameKind kind,
00072                                                  const Rect* initialBounds, Boolean resizeable)
00073        :      MRJFrame(frameRef),
00074               mHandler(handler), mWindow(NULL), mBounds(*initialBounds)
00075 {
00076        Boolean hasGoAway = true;
00077        SInt16 windowProc = documentProc;
00078        SInt16 resizeHeight = resizeable ? 15 : 0;
00079        
00080        switch (kind) {
00081        case eBorderlessModelessWindowFrame:
00082               hasGoAway = false;
00083               windowProc = plainDBox;
00084               // mBounds.bottom += resizeHeight;
00085               resizeable = false;
00086               break;
00087        case eModelessWindowFrame:
00088        case eModelessDialogFrame:
00089               hasGoAway = true;
00090               windowProc = resizeable ? zoomDocProc : documentProc;
00091               // mBounds.bottom += resizeHeight;
00092               break;
00093        case eModalWindowFrame:
00094               hasGoAway = true;
00095               // We have to allow resizeable modal windows.
00096               windowProc = resizeable ? documentProc : movableDBoxProc;
00097               break;
00098        }
00099        
00100        mWindow = ::NewCWindow(NULL, &mBounds, "\p", false, windowProc, WindowPtr(-1), hasGoAway, long(this));
00101        if (mWindow != NULL) {
00102               Point zeroPt = { 0, 0 };
00103               ::JMSetFrameVisibility(frameRef, mWindow, zeroPt, mWindow->clipRgn);
00104        }
00105 }
00106 
00107 TopLevelFrame::~TopLevelFrame()
00108 {
00109        // make sure the window is hidden (and unregistered with the browser).
00110        showHide(false);
00111 
00112        // make sure this port isn't ever current again.
00113        ::UnsetPort(mWindow);
00114 
00115        if (mWindow != NULL)
00116               ::DisposeWindow(mWindow);
00117 }
00118 
00119 void TopLevelFrame::setSize(const Rect* newSize)
00120 {
00121        mBounds = *newSize;
00122 
00123        if (mWindow != NULL) {
00124               SInt16 width = newSize->right - newSize->left;
00125               SInt16 height = newSize->bottom - newSize->top;
00126               ::SizeWindow(mWindow, width, height, true);
00127               ::MoveWindow(mWindow, newSize->left, newSize->top, false);
00128        }
00129 }
00130 
00131 void TopLevelFrame::invalRect(const Rect* invalidRect)
00132 {
00133        if (mWindow != NULL) {
00134               ::InvalRect(invalidRect);
00135        }
00136 }
00137 
00138 void TopLevelFrame::showHide(Boolean visible)
00139 {
00140        if (mWindow != NULL && visible != IsWindowVisible(mWindow)) {
00141               if (visible) {
00142 #if !defined(USE_ALT_WINDOW_HANDLING)            
00143                      // Have to notify the browser that this window exists, so that it will receive events.
00144                      thePluginManager2->RegisterWindow(mHandler, mWindow);
00145                      // the plugin manager takes care of showing the window.
00146                      // ::ShowWindow(mWindow);
00147                      // ::SelectWindow(mWindow);
00148 #else
00149             AltRegisterWindow(mHandler, mWindow);
00150 #endif
00151               } else {
00152 #if defined(USE_ALT_WINDOW_HANDLING)             
00153             AltUnregisterWindow(mHandler, mWindow);
00154 #else
00155                      // the plugin manager takes care of hiding the window.
00156                      // ::HideWindow(mWindow);
00157                      // Let the browser know it doesn't have to send events anymore.
00158                      thePluginManager2->UnregisterWindow(mHandler, mWindow);
00159 #endif
00160                      activate(false);
00161               }
00162               
00163               // ::ShowHide(mWindow, visible);
00164        }
00165 }
00166 
00167 void TopLevelFrame::setTitle(const StringPtr title)
00168 {
00169        if (mWindow != NULL) {
00170               ::SetWTitle(mWindow, title);
00171        }
00172 }
00173 
00174 void TopLevelFrame::checkUpdate()
00175 {
00176 }
00177 
00178 void TopLevelFrame::reorder(ReorderRequest request)
00179 {
00180        switch (request) {
00181        case eBringToFront:         /* bring the window to front */
00182               ::BringToFront(mWindow);
00183               break;
00184        case eSendToBack:           /* send the window to back */
00185               ::SendBehind(mWindow, NULL);
00186               break;
00187        case eSendBehindFront:      /* send the window behind the front window */
00188               WindowPtr frontWindow = ::FrontWindow();
00189               if (mWindow == frontWindow) {
00190                      ::SendBehind(mWindow, GetNextWindow(mWindow));
00191               } else {
00192                      ::SendBehind(mWindow, frontWindow);
00193               }
00194               break;
00195        }
00196 }
00197 
00198 void TopLevelFrame::setResizeable(Boolean resizeable)
00199 {
00200        // this might have to recreate the window, no?
00201 }
00202 
00203 static void computeBounds(WindowRef window, Rect* bounds)
00204 {
00205        LocalPort port(window);
00206        port.Enter();
00207        
00208               Point position = { 0, 0 };
00209               ::LocalToGlobal(&position);
00210               
00211               *bounds = window->portRect;
00212        
00213        port.Exit();
00214        
00215        ::OffsetRect(bounds, position.h, position.v);
00216 }
00217 
00218 void TopLevelFrame::activate(Boolean active)
00219 {
00220        focusEvent(active);
00221        MRJFrame::activate(active);
00222 }
00223 
00224 void TopLevelFrame::click(const EventRecord* event)
00225 {
00226        Point where = event->where;
00227        SInt16 modifiers = event->modifiers;
00228        WindowRef hitWindow;
00229        short partCode = ::FindWindow(where, &hitWindow);
00230        switch (partCode) {
00231        case inContent:
00232               ::SelectWindow(mWindow);
00233               MRJFrame::click(event);
00234               break;
00235        case inDrag:
00236               {
00237                      Rect bounds = (**GetGrayRgn()).rgnBBox;
00238                      DragWindow(mWindow, where, &bounds);
00239                      computeBounds(mWindow, &bounds);
00240                      ::JMSetFrameSize(mFrameRef, &bounds);
00241 
00242                      Point zeroPt = { 0, 0 };
00243                      ::JMSetFrameVisibility(mFrameRef, mWindow, zeroPt, mWindow->clipRgn);
00244               }
00245               break;
00246        case inGrow:
00247               Rect limits = { 30, 30, 5000, 5000 };
00248               long result = GrowWindow(mWindow, where, &limits);
00249               if (result != 0) {
00250                      short width = (result & 0xFFFF);
00251                      short height = (result >> 16) & 0xFFFF;
00252                      Rect newBounds;
00253                      topLeft(newBounds) = topLeft(mBounds);
00254                      newBounds.right = newBounds.left + width;
00255                      newBounds.bottom = newBounds.top + height;
00256                      ::JMSetFrameSize(mFrameRef, &newBounds);
00257 
00258                      Point zeroPt = { 0, 0 };
00259                      ::JMSetFrameVisibility(mFrameRef, mWindow, zeroPt, mWindow->clipRgn);
00260               }
00261               break;
00262        case inGoAway:
00263               if (::TrackGoAway(mWindow, where))
00264                      ::JMFrameGoAway(mFrameRef);
00265               break;
00266        case inZoomIn:
00267        case inZoomOut:
00268               if (::TrackBox(mWindow, where, partCode)) {
00269                      ZoomWindow(mWindow, partCode, true);
00270                      computeBounds(mWindow, &mBounds);
00271                      ::JMSetFrameSize(mFrameRef, &mBounds);
00272               }
00273               break;
00274        case inCollapseBox:
00275               break;
00276        }
00277 }
00278 
00279 WindowRef TopLevelFrame::getWindow()
00280 {
00281        return mWindow;
00282 }
00283 
00284 GrafPtr TopLevelFrame::getPort()
00285 {
00286        return mWindow;
00287 }
00288 
00289 static void UnsetPort(GrafPtr port)
00290 {
00291        GrafPtr curPort;
00292        ::GetPort(&curPort);
00293        if (curPort == port) {
00294               ::GetWMgrPort(&port);
00295               ::SetPort(port);
00296        }
00297 }
00298 
00299 static short getModifiers()
00300 {
00301        EventRecord event;
00302        ::OSEventAvail(0, &event);
00303        return event.modifiers;
00304 }