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