Files
Mozilla/mozilla/widget/src/mac/nsMacWindow.cpp
pinkerton%netscape.com f938f75ace Added specific mac toolbox include files (and helper macros) not covered in the widget prefix file.
git-svn-id: svn://10.0.0.236/trunk@14498 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-12 05:59:31 +00:00

270 lines
8.2 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include <LowMem.h>
#include "nsWindow.h"
#include "nsMacWindow.h"
#include "nsMacEventHandler.h"
// from MacHeaders.c
#ifndef topLeft
#define topLeft(r) (((Point *) &(r))[0])
#endif
#ifndef botRight
#define botRight(r) (((Point *) &(r))[1])
#endif
const short kWindowTitleBarHeight = 20;
NS_IMPL_ADDREF(nsMacWindow);
NS_IMPL_RELEASE(nsMacWindow);
//-------------------------------------------------------------------------
//
// nsMacWindow constructor
//
//-------------------------------------------------------------------------
nsMacWindow::nsMacWindow() : nsWindow()
, mWindowMadeHere(PR_FALSE), mMacEventHandler(new nsMacEventHandler(this))
{
NS_INIT_REFCNT();
strcpy(gInstanceClassName, "nsMacWindow");
}
//-------------------------------------------------------------------------
//
// nsMacWindow destructor
//
//-------------------------------------------------------------------------
nsMacWindow::~nsMacWindow()
{
if (mWindowPtr)
{
nsRefData* theRefData = (nsRefData*)::GetWRefCon(mWindowPtr);
if (mWindowMadeHere)
::CloseWindow(mWindowPtr);
else
::SetWRefCon(mWindowPtr, theRefData->GetUserData()); // restore the refCon if we did not create the window
mWindowPtr = nsnull;
delete theRefData;
}
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
nsresult nsMacWindow::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
static NS_DEFINE_IID(kIWindowIID, NS_IWINDOW_IID); //¥¥¥
if (aIID.Equals(kIWindowIID)) {
*aInstancePtr = (void*) ((nsIWidget*)(nsISupports*)this);
AddRef();
return NS_OK;
}
return nsWindow::QueryInterface(aIID,aInstancePtr);
}
//-------------------------------------------------------------------------
//
// Utility method for implementing both Create(nsIWidget ...) and
// Create(nsNativeWidget...)
//-------------------------------------------------------------------------
nsresult nsMacWindow::StandardCreate(nsIWidget *aParent,
const nsRect &aRect,
EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext,
nsIAppShell *aAppShell,
nsIToolkit *aToolkit,
nsWidgetInitData *aInitData,
nsNativeWidget aNativeParent)
{
// build the main native window
if (aNativeParent == nsnull)
{
Rect wRect;
nsRectToMacRect(aRect, wRect);
wRect.top += ::LMGetMBarHeight() + kWindowTitleBarHeight;
mWindowPtr = ::NewCWindow(nil, &wRect, "\p-", false, 0, (GrafPort*)-1, true, (long)nsnull);
mWindowMadeHere = PR_TRUE;
}
else
{
mWindowPtr = (WindowPtr)aNativeParent;
mWindowMadeHere = PR_FALSE;
}
// set the refData
nsRefData* theRefData = new nsRefData();
if (theRefData == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
theRefData->SetNSMacWindow(this);
theRefData->SetUserData(::GetWRefCon(mWindowPtr)); // save the actual refCon in case we did not create the window
::SetWRefCon(mWindowPtr, (long)theRefData);
// reset the coordinates to (0,0) because it's the top level widget
nsRect bounds(0, 0, aRect.width, aRect.height);
// init base class
nsWindow::StandardCreate(aParent, bounds, aHandleEventFunction,
aContext, aAppShell, aToolkit, aInitData);
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Create a nsMacWindow using a native window provided by the application
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsMacWindow::Create(nsNativeWidget aNativeParent, // this is a windowPtr
const nsRect &aRect,
EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext,
nsIAppShell *aAppShell,
nsIToolkit *aToolkit,
nsWidgetInitData *aInitData)
{
return(StandardCreate(nsnull, aRect, aHandleEventFunction,
aContext, aAppShell, aToolkit, aInitData,
aNativeParent));
}
//-------------------------------------------------------------------------
//
// Hide or show this window
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsMacWindow::Show(PRBool bState)
{
nsWindow::Show(bState);
// we need to make sure we call ::Show/HideWindow() to generate the
// necessary activate/deactivate events. Calling ::ShowHide() is
// not adequate (pinkerton).
if ( bState )
::ShowWindow(mWindowPtr);
else
::HideWindow(mWindowPtr);
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Move this window
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsMacWindow::Move(PRUint32 aX, PRUint32 aY)
{
//¥TODO: We should check that the new window belongs to one of the screens
// but "qd.screenBits.bounds" is not the right way to do it.
Rect screenRect = qd.screenBits.bounds;
::InsetRect(&screenRect, 4, 4);
screenRect.top += ::LMGetMBarHeight() + kWindowTitleBarHeight;
short windowWidth = mWindowPtr->portRect.right - mWindowPtr->portRect.left;
if (((PRInt32)aX) < screenRect.left - windowWidth)
aX = screenRect.left - windowWidth;
else if (((PRInt32)aX) > screenRect.right)
aX = screenRect.right;
if (((PRInt32)aY) < screenRect.top)
aY = screenRect.top;
else if (((PRInt32)aY) > screenRect.bottom)
aY = screenRect.bottom;
// propagate the event in global coordinates
nsWindow::Move(aX, aY);
// reset the coordinates to (0,0) because it's the top level widget
mBounds.x = 0;
mBounds.y = 0;
// move the window if it has not been moved yet
// (ie. if this function isn't called in response to a DragWindow event)
Point macPoint;
macPoint = topLeft(mWindowPtr->portRect);
::LocalToGlobal(&macPoint);
if ((macPoint.h != aX) || (macPoint.v != aY)) {
::MoveWindow(mWindowPtr, aX, aY, false);
}
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Resize this window
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsMacWindow::Resize(PRUint32 aWidth, PRUint32 aHeight, PRBool aRepaint)
{
// move the window if it has not been moved yet
// (ie. if this function isn't called in response to a GrowWindow event)
Rect macRect = mWindowPtr->portRect;
if (((macRect.right - macRect.left) != aWidth)
|| ((macRect.bottom - macRect.top) != aHeight)) {
::SizeWindow(mWindowPtr, aWidth, aHeight, aRepaint);
}
nsWindow::Resize(aWidth, aHeight, aRepaint);
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Handle OS events
//
//-------------------------------------------------------------------------
PRBool nsMacWindow::HandleOSEvent(
EventRecord& aOSEvent)
{
PRBool retVal;
if (mMacEventHandler.get())
retVal = mMacEventHandler->HandleOSEvent(aOSEvent);
else
retVal = PR_FALSE;
return retVal;
}
//-------------------------------------------------------------------------
//
// Handle Menu commands
//
//-------------------------------------------------------------------------
PRBool nsMacWindow::HandleMenuCommand(
EventRecord& aOSEvent,
long aMenuResult)
{
PRBool retVal;
if (mMacEventHandler.get())
retVal = mMacEventHandler->HandleMenuCommand(aOSEvent, aMenuResult);
else
retVal = PR_FALSE;
return retVal;
}