1999-07-18 06:23:45 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* The contents of this file are subject to the Netscape Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/NPL/
|
1999-07-18 06:23:45 +00:00
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
1999-07-18 06:23:45 +00:00
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
1999-07-18 06:23:45 +00:00
|
|
|
* Communications Corporation. Portions created by Netscape are
|
1999-11-06 03:40:37 +00:00
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
1999-07-18 06:23:45 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "nsMenuPopupFrame.h"
|
1999-07-20 07:28:39 +00:00
|
|
|
#include "nsXULAtoms.h"
|
1999-07-20 09:50:48 +00:00
|
|
|
#include "nsHTMLAtoms.h"
|
1999-07-18 06:23:45 +00:00
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "prtypes.h"
|
|
|
|
#include "nsIAtom.h"
|
|
|
|
#include "nsIPresContext.h"
|
|
|
|
#include "nsIStyleContext.h"
|
|
|
|
#include "nsCSSRendering.h"
|
|
|
|
#include "nsINameSpaceManager.h"
|
1999-07-20 08:37:03 +00:00
|
|
|
#include "nsIViewManager.h"
|
|
|
|
#include "nsWidgetsCID.h"
|
1999-07-22 09:01:55 +00:00
|
|
|
#include "nsMenuFrame.h"
|
1999-09-21 01:03:00 +00:00
|
|
|
#include "nsIPopupSetFrame.h"
|
1999-11-23 03:02:01 +00:00
|
|
|
#include "nsIDOMWindow.h"
|
|
|
|
#include "nsIDOMScreen.h"
|
|
|
|
#include "nsIScriptGlobalObject.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsIScriptObjectOwner.h"
|
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIDeviceContext.h"
|
|
|
|
#include "nsRect.h"
|
1999-07-20 08:37:03 +00:00
|
|
|
|
|
|
|
const PRInt32 kMaxZ = 0x7fffffff; //XXX: Shouldn't there be a define somewhere for MaxInt for PRInt32
|
1999-07-18 06:23:45 +00:00
|
|
|
|
1999-09-21 01:03:00 +00:00
|
|
|
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
|
1999-07-18 06:23:45 +00:00
|
|
|
|
|
|
|
// NS_NewMenuPopupFrame
|
|
|
|
//
|
|
|
|
// Wrapper for creating a new menu popup container
|
|
|
|
//
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewMenuPopupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
1999-07-18 06:23:45 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
|
|
|
if (nsnull == aNewFrame) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
1999-12-04 23:49:50 +00:00
|
|
|
nsMenuPopupFrame* it = new (aPresShell) nsMenuPopupFrame;
|
1999-07-18 06:23:45 +00:00
|
|
|
if ( !it )
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
*aNewFrame = it;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-07-21 07:42:16 +00:00
|
|
|
NS_IMETHODIMP_(nsrefcnt)
|
|
|
|
nsMenuPopupFrame::AddRef(void)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP_(nsrefcnt)
|
|
|
|
nsMenuPopupFrame::Release(void)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsMenuPopupFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
|
|
{
|
|
|
|
if (NULL == aInstancePtr) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aInstancePtr = NULL;
|
|
|
|
|
|
|
|
if (aIID.Equals(nsIMenuParent::GetIID())) {
|
|
|
|
*aInstancePtr = (void*)(nsIMenuParent*) this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsBoxFrame::QueryInterface(aIID, aInstancePtr);
|
|
|
|
}
|
|
|
|
|
1999-07-18 06:23:45 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// nsMenuPopupFrame cntr
|
|
|
|
//
|
|
|
|
nsMenuPopupFrame::nsMenuPopupFrame()
|
1999-09-21 01:03:00 +00:00
|
|
|
:mCurrentMenu(nsnull)
|
1999-07-18 06:23:45 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
} // cntr
|
|
|
|
|
1999-07-20 07:28:39 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsMenuPopupFrame::Init(nsIPresContext* aPresContext,
|
1999-07-20 07:28:39 +00:00
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParent,
|
|
|
|
nsIStyleContext* aContext,
|
|
|
|
nsIFrame* aPrevInFlow)
|
|
|
|
{
|
1999-07-21 02:56:23 +00:00
|
|
|
nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
1999-07-20 09:50:48 +00:00
|
|
|
|
1999-10-26 04:44:41 +00:00
|
|
|
// XXX Hack
|
1999-11-24 06:03:41 +00:00
|
|
|
mPresContext = aPresContext;
|
1999-10-26 04:44:41 +00:00
|
|
|
|
1999-07-20 10:35:24 +00:00
|
|
|
CreateViewForFrame(aPresContext, this, aContext, PR_TRUE);
|
1999-07-20 08:37:03 +00:00
|
|
|
|
|
|
|
// Now that we've made a view, remove it and insert it at the correct
|
|
|
|
// position in the view hierarchy (as the root view). We do this so that we
|
|
|
|
// can draw the menus outside the confines of the window.
|
|
|
|
nsIView* ourView;
|
1999-11-24 06:03:41 +00:00
|
|
|
GetView(aPresContext, &ourView);
|
1999-07-20 08:37:03 +00:00
|
|
|
|
|
|
|
nsIFrame* parent;
|
1999-11-24 06:03:41 +00:00
|
|
|
aParent->GetParentWithView(aPresContext, &parent);
|
1999-07-20 08:37:03 +00:00
|
|
|
nsIView* parentView;
|
1999-11-24 06:03:41 +00:00
|
|
|
parent->GetView(aPresContext, &parentView);
|
1999-07-20 08:37:03 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
parentView->GetViewManager(*getter_AddRefs(viewManager));
|
|
|
|
|
|
|
|
// Remove the view from its old position.
|
|
|
|
viewManager->RemoveChild(parentView, ourView);
|
|
|
|
|
|
|
|
// Reinsert ourselves as the root view with a maximum z-index.
|
|
|
|
nsIView* rootView;
|
|
|
|
viewManager->GetRootView(rootView);
|
|
|
|
viewManager->InsertChild(rootView, ourView, kMaxZ);
|
|
|
|
|
1999-07-31 01:43:33 +00:00
|
|
|
// XXX Hack. Change our transparency to be non-transparent
|
|
|
|
// until the bug related to update of transparency on show/hide
|
|
|
|
// is fixed.
|
|
|
|
viewManager->SetViewContentTransparency(ourView, PR_FALSE);
|
|
|
|
|
1999-07-20 08:37:03 +00:00
|
|
|
// Create a widget for ourselves.
|
|
|
|
nsWidgetInitData widgetData;
|
|
|
|
ourView->SetZIndex(kMaxZ);
|
1999-07-27 04:27:17 +00:00
|
|
|
widgetData.mWindowType = eWindowType_popup;
|
|
|
|
widgetData.mBorderStyle = eBorderStyle_default;
|
1999-09-26 22:45:35 +00:00
|
|
|
|
1999-09-28 23:25:48 +00:00
|
|
|
// XXX make sure we are hidden (shouldn't this be done automatically?)
|
|
|
|
ourView->SetVisibility(nsViewVisibility_kHide);
|
1999-09-26 22:45:35 +00:00
|
|
|
#ifdef XP_MAC
|
|
|
|
printf("XP Popups: This is a nag to indicate that an inconsistent hack is being done on the Mac for popups.\n");
|
|
|
|
static NS_DEFINE_IID(kCPopupCID, NS_POPUP_CID);
|
|
|
|
ourView->CreateWidget(kCPopupCID, &widgetData, nsnull);
|
|
|
|
#else
|
1999-07-20 08:37:03 +00:00
|
|
|
static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID);
|
1999-09-26 22:45:35 +00:00
|
|
|
ourView->CreateWidget(kCChildCID, &widgetData, nsnull);
|
|
|
|
#endif
|
|
|
|
|
1999-09-21 01:03:00 +00:00
|
|
|
return rv;
|
1999-07-20 07:28:39 +00:00
|
|
|
}
|
1999-07-20 09:35:35 +00:00
|
|
|
|
1999-11-18 21:05:43 +00:00
|
|
|
PRBool
|
|
|
|
nsMenuPopupFrame::GetInitialAlignment()
|
|
|
|
{
|
|
|
|
// by default we are vertical unless horizontal is specifically specified
|
|
|
|
nsString value;
|
|
|
|
|
|
|
|
mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value);
|
|
|
|
if (value.EqualsIgnoreCase("horizontal"))
|
|
|
|
return PR_TRUE;
|
|
|
|
else
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1999-07-20 09:35:35 +00:00
|
|
|
void
|
|
|
|
nsMenuPopupFrame::GetViewOffset(nsIViewManager* aManager, nsIView* aView,
|
|
|
|
nsPoint& aPoint)
|
|
|
|
{
|
|
|
|
aPoint.x = 0;
|
|
|
|
aPoint.y = 0;
|
|
|
|
|
|
|
|
nsIView *parent;
|
|
|
|
nsRect bounds;
|
|
|
|
|
|
|
|
parent = aView;
|
|
|
|
while (nsnull != parent) {
|
|
|
|
parent->GetBounds(bounds);
|
|
|
|
aPoint.x += bounds.x;
|
|
|
|
aPoint.y += bounds.y;
|
|
|
|
parent->GetParent(parent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-09-10 08:47:12 +00:00
|
|
|
void
|
1999-10-26 04:44:41 +00:00
|
|
|
nsMenuPopupFrame::GetNearestEnclosingView(nsIPresContext* aPresContext, nsIFrame* aStartFrame, nsIView** aResult)
|
1999-09-10 08:47:12 +00:00
|
|
|
{
|
|
|
|
*aResult = nsnull;
|
1999-10-26 04:44:41 +00:00
|
|
|
aStartFrame->GetView(aPresContext, aResult);
|
1999-09-10 08:47:12 +00:00
|
|
|
if (!*aResult) {
|
|
|
|
nsIFrame* parent;
|
1999-10-26 04:44:41 +00:00
|
|
|
aStartFrame->GetParentWithView(aPresContext, &parent);
|
1999-09-10 08:47:12 +00:00
|
|
|
if (parent)
|
1999-10-26 04:44:41 +00:00
|
|
|
parent->GetView(aPresContext, aResult);
|
1999-09-10 08:47:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-07-20 09:35:35 +00:00
|
|
|
nsresult
|
1999-11-24 06:03:41 +00:00
|
|
|
nsMenuPopupFrame::SyncViewWithFrame(nsIPresContext* aPresContext,
|
1999-09-10 08:47:12 +00:00
|
|
|
PRBool aOnMenuBar,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRInt32 aXPos, PRInt32 aYPos)
|
1999-07-20 09:35:35 +00:00
|
|
|
{
|
1999-11-24 06:03:41 +00:00
|
|
|
NS_ENSURE_ARG(aPresContext);
|
1999-07-20 09:35:35 +00:00
|
|
|
nsPoint parentPos;
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
|
1999-09-10 08:47:12 +00:00
|
|
|
//Get the nearest enclosing parent view to aFrame.
|
1999-07-20 09:35:35 +00:00
|
|
|
nsIView* parentView = nsnull;
|
1999-11-24 06:03:41 +00:00
|
|
|
GetNearestEnclosingView(aPresContext, aFrame, &parentView);
|
1999-09-10 08:47:12 +00:00
|
|
|
if (!parentView)
|
|
|
|
return NS_OK;
|
1999-07-20 09:35:35 +00:00
|
|
|
|
|
|
|
parentView->GetViewManager(*getter_AddRefs(viewManager));
|
|
|
|
GetViewOffset(viewManager, parentView, parentPos);
|
|
|
|
nsIView* view = nsnull;
|
1999-11-24 06:03:41 +00:00
|
|
|
GetView(aPresContext, &view);
|
1999-07-20 09:35:35 +00:00
|
|
|
|
|
|
|
nsIView* containingView = nsnull;
|
|
|
|
nsPoint offset;
|
1999-11-24 06:03:41 +00:00
|
|
|
aFrame->GetOffsetFromView(aPresContext, offset, &containingView);
|
1999-07-20 09:35:35 +00:00
|
|
|
|
|
|
|
nsRect parentRect;
|
1999-09-10 08:47:12 +00:00
|
|
|
aFrame->GetRect(parentRect);
|
1999-07-20 09:35:35 +00:00
|
|
|
|
1999-09-29 03:30:04 +00:00
|
|
|
const nsStyleDisplay* disp;
|
|
|
|
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp);
|
|
|
|
PRBool viewIsVisible = (NS_STYLE_VISIBILITY_VISIBLE == disp->mVisible);
|
|
|
|
nsViewVisibility oldVisibility;
|
|
|
|
view->GetVisibility(oldVisibility);
|
|
|
|
PRBool viewWasVisible = (oldVisibility == nsViewVisibility_kShow);
|
|
|
|
|
|
|
|
if (viewWasVisible && (! viewIsVisible)) {
|
|
|
|
view->SetVisibility(nsViewVisibility_kHide);
|
|
|
|
}
|
|
|
|
|
1999-11-23 03:02:01 +00:00
|
|
|
float p2t, t2p;
|
1999-11-24 06:03:41 +00:00
|
|
|
aPresContext->GetScaledPixelsToTwips(&p2t);
|
1999-11-23 03:02:01 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDeviceContext> dx;
|
|
|
|
viewManager->GetDeviceContext(*getter_AddRefs(dx));
|
|
|
|
dx->GetAppUnitsToDevUnits(t2p);
|
|
|
|
|
|
|
|
PRInt32 xpos;
|
|
|
|
PRInt32 ypos;
|
1999-07-20 09:35:35 +00:00
|
|
|
viewManager->ResizeView(view, mRect.width, mRect.height);
|
1999-09-10 08:47:12 +00:00
|
|
|
if (aXPos != -1 || aYPos != -1) {
|
|
|
|
// Convert the screen coords to twips
|
1999-11-23 03:02:01 +00:00
|
|
|
xpos = NSIntPixelsToTwips(aXPos, p2t);
|
|
|
|
ypos = NSIntPixelsToTwips(aYPos, p2t);
|
|
|
|
xpos += offset.x;
|
|
|
|
ypos += offset.y;
|
|
|
|
} else if (aOnMenuBar) {
|
|
|
|
xpos = parentPos.x + offset.x;
|
|
|
|
ypos = parentPos.y + parentRect.height + offset.y;
|
|
|
|
} else {
|
|
|
|
xpos = parentPos.x + parentRect.width + offset.x;
|
|
|
|
ypos = parentPos.y + offset.y;
|
1999-09-10 08:47:12 +00:00
|
|
|
}
|
1999-11-23 03:02:01 +00:00
|
|
|
viewManager->MoveViewTo(view, xpos, ypos);
|
1999-09-10 08:47:12 +00:00
|
|
|
|
1999-11-23 03:02:01 +00:00
|
|
|
// Check if we fit on the screen, if not, resize and/or move so we do
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
1999-11-24 06:03:41 +00:00
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
1999-11-23 03:02:01 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
presShell->GetDocument(getter_AddRefs(document));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject;
|
1999-12-03 09:24:22 +00:00
|
|
|
document->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject));
|
1999-11-23 03:02:01 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMWindow> window(do_QueryInterface(scriptGlobalObject));
|
|
|
|
nsCOMPtr<nsIDOMScreen> screen;
|
|
|
|
window->GetScreen(getter_AddRefs(screen));
|
|
|
|
PRInt32 screenWidth;
|
|
|
|
PRInt32 screenHeight;
|
|
|
|
screen->GetAvailWidth(&screenWidth);
|
|
|
|
screen->GetAvailHeight(&screenHeight);
|
|
|
|
|
|
|
|
PRInt32 screenLeft; // May be negative on MacOS!
|
|
|
|
PRInt32 screenTop; // May be negative on MacOS!
|
|
|
|
screen->GetAvailLeft(&screenLeft);
|
|
|
|
screen->GetAvailTop(&screenTop);
|
|
|
|
|
|
|
|
PRInt32 screenRight;
|
|
|
|
if(screenLeft<0)
|
|
|
|
screenRight = screenWidth + screenLeft;
|
|
|
|
else
|
|
|
|
screenRight = screenWidth - screenLeft;
|
|
|
|
|
|
|
|
PRInt32 screenBottom;
|
|
|
|
if(screenTop<0)
|
|
|
|
screenBottom = screenHeight + screenTop;
|
|
|
|
else
|
|
|
|
screenBottom = screenHeight - screenTop;
|
|
|
|
|
|
|
|
screenWidth = NSIntPixelsToTwips(screenWidth, p2t);
|
|
|
|
screenHeight = NSIntPixelsToTwips(screenHeight, p2t);
|
|
|
|
screenRight = NSIntPixelsToTwips(screenRight, p2t);
|
|
|
|
screenBottom = NSIntPixelsToTwips(screenBottom, p2t);
|
|
|
|
|
|
|
|
if(mRect.width > screenWidth || mRect.height > screenHeight) {
|
|
|
|
if(mRect.width > screenWidth) mRect.width = screenWidth;
|
|
|
|
|
|
|
|
if(mRect.height > screenHeight) mRect.height = screenHeight;
|
|
|
|
|
|
|
|
viewManager->ResizeView(view, mRect.width, mRect.height);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get pixel distance from popup widget 0,0 to screen 0,0
|
|
|
|
nsCOMPtr<nsIWidget> widget;
|
|
|
|
view->GetWidget(*getter_AddRefs(widget));
|
|
|
|
|
|
|
|
nsRect inRect, outRect;
|
|
|
|
inRect.x = 0;
|
|
|
|
inRect.y = 0;
|
|
|
|
widget->WidgetToScreen(inRect, outRect);
|
|
|
|
|
|
|
|
if(outRect.x < screenLeft || outRect.y < screenTop) {
|
|
|
|
if(outRect.x < screenLeft) {
|
|
|
|
PRInt32 diff = NSIntPixelsToTwips(screenLeft - outRect.x,p2t);
|
|
|
|
if(diff>0)
|
|
|
|
xpos += diff;
|
|
|
|
else
|
|
|
|
xpos -= diff;
|
|
|
|
}
|
|
|
|
if(outRect.y < screenTop) {
|
|
|
|
PRInt32 diff = NSIntPixelsToTwips(screenTop - outRect.y,p2t);
|
|
|
|
if(diff>0)
|
|
|
|
ypos += diff;
|
|
|
|
else
|
|
|
|
ypos -= diff;
|
|
|
|
}
|
|
|
|
|
|
|
|
viewManager->MoveViewTo(view, xpos, ypos);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((NSIntPixelsToTwips(outRect.x,p2t) + mRect.width) > screenRight) {
|
|
|
|
xpos -= (NSIntPixelsToTwips(outRect.x,p2t) + mRect.width) - screenRight;
|
|
|
|
viewManager->MoveViewTo(view, xpos, ypos);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((NSIntPixelsToTwips(outRect.y,p2t) + mRect.height) > screenBottom) {
|
|
|
|
ypos -= (NSIntPixelsToTwips(outRect.y,p2t) + mRect.height) - screenBottom;
|
|
|
|
viewManager->MoveViewTo(view, xpos, ypos);
|
|
|
|
}
|
1999-07-20 09:35:35 +00:00
|
|
|
|
1999-09-29 03:30:04 +00:00
|
|
|
if ((! viewWasVisible) && viewIsVisible) {
|
|
|
|
view->SetVisibility(nsViewVisibility_kShow);
|
|
|
|
}
|
|
|
|
|
1999-07-20 09:35:35 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsMenuPopupFrame::DidReflow(nsIPresContext* aPresContext,
|
1999-07-20 09:35:35 +00:00
|
|
|
nsDidReflowStatus aStatus)
|
|
|
|
{
|
1999-09-24 05:22:55 +00:00
|
|
|
// Copied from nsContainerFrame reflow WITHOUT the call
|
|
|
|
// nsFrame::DidReflow(). nsFrame::DidReflow() will move us to the
|
|
|
|
// wrong place.
|
|
|
|
nsresult result = NS_OK; /* = nsFrame::DidReflow(aPresContext, aStatus) */
|
|
|
|
|
|
|
|
NS_FRAME_TRACE_OUT("nsContainerFrame::DidReflow");
|
|
|
|
return result;
|
1999-07-20 09:35:35 +00:00
|
|
|
}
|
1999-07-21 07:42:16 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-09-21 01:03:00 +00:00
|
|
|
nsMenuPopupFrame::GetNextMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult)
|
1999-07-21 07:42:16 +00:00
|
|
|
{
|
1999-09-21 01:03:00 +00:00
|
|
|
nsIFrame* currFrame = nsnull;
|
|
|
|
nsIFrame* startFrame = nsnull;
|
1999-07-22 09:01:55 +00:00
|
|
|
if (aStart) {
|
1999-09-21 01:03:00 +00:00
|
|
|
aStart->QueryInterface(kIFrameIID, (void**)&currFrame);
|
|
|
|
if (currFrame) {
|
|
|
|
startFrame = currFrame;
|
1999-07-22 09:01:55 +00:00
|
|
|
currFrame->GetNextSibling(&currFrame);
|
1999-09-21 01:03:00 +00:00
|
|
|
}
|
1999-07-22 09:01:55 +00:00
|
|
|
}
|
|
|
|
else currFrame = mFrames.FirstChild();
|
|
|
|
|
1999-07-22 01:59:09 +00:00
|
|
|
while (currFrame) {
|
1999-07-21 07:42:16 +00:00
|
|
|
nsCOMPtr<nsIContent> current;
|
1999-07-22 01:59:09 +00:00
|
|
|
currFrame->GetContent(getter_AddRefs(current));
|
|
|
|
|
1999-07-21 07:42:16 +00:00
|
|
|
// See if it's a menu item.
|
1999-07-26 01:35:39 +00:00
|
|
|
if (IsValidItem(current)) {
|
1999-09-21 01:03:00 +00:00
|
|
|
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
|
|
|
|
*aResult = menuFrame.get();
|
|
|
|
NS_IF_ADDREF(*aResult);
|
1999-07-21 07:42:16 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-07-22 01:59:09 +00:00
|
|
|
currFrame->GetNextSibling(&currFrame);
|
1999-07-21 07:42:16 +00:00
|
|
|
}
|
|
|
|
|
1999-07-22 01:59:09 +00:00
|
|
|
currFrame = mFrames.FirstChild();
|
|
|
|
|
1999-07-21 07:42:16 +00:00
|
|
|
// Still don't have anything. Try cycling from the beginning.
|
1999-09-21 01:03:00 +00:00
|
|
|
while (currFrame && currFrame != startFrame) {
|
1999-07-21 07:42:16 +00:00
|
|
|
nsCOMPtr<nsIContent> current;
|
1999-07-22 01:59:09 +00:00
|
|
|
currFrame->GetContent(getter_AddRefs(current));
|
1999-07-21 07:42:16 +00:00
|
|
|
|
|
|
|
// See if it's a menu item.
|
1999-07-26 01:35:39 +00:00
|
|
|
if (IsValidItem(current)) {
|
1999-09-21 01:03:00 +00:00
|
|
|
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
|
|
|
|
*aResult = menuFrame.get();
|
|
|
|
NS_IF_ADDREF(*aResult);
|
1999-07-21 07:42:16 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-07-22 01:59:09 +00:00
|
|
|
|
|
|
|
currFrame->GetNextSibling(&currFrame);
|
1999-07-21 07:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// No luck. Just return our start value.
|
|
|
|
*aResult = aStart;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-09-21 01:03:00 +00:00
|
|
|
nsMenuPopupFrame::GetPreviousMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult)
|
1999-07-21 07:42:16 +00:00
|
|
|
{
|
1999-09-21 01:03:00 +00:00
|
|
|
nsIFrame* currFrame = nsnull;
|
|
|
|
nsIFrame* startFrame = nsnull;
|
1999-07-22 09:01:55 +00:00
|
|
|
if (aStart) {
|
1999-09-21 01:03:00 +00:00
|
|
|
aStart->QueryInterface(kIFrameIID, (void**)&currFrame);
|
|
|
|
if (currFrame) {
|
|
|
|
startFrame = currFrame;
|
1999-07-22 09:01:55 +00:00
|
|
|
currFrame = mFrames.GetPrevSiblingFor(currFrame);
|
1999-09-21 01:03:00 +00:00
|
|
|
}
|
1999-07-22 09:01:55 +00:00
|
|
|
}
|
|
|
|
else currFrame = mFrames.LastChild();
|
|
|
|
|
1999-07-22 01:59:09 +00:00
|
|
|
while (currFrame) {
|
1999-07-21 07:42:16 +00:00
|
|
|
nsCOMPtr<nsIContent> current;
|
1999-07-22 01:59:09 +00:00
|
|
|
currFrame->GetContent(getter_AddRefs(current));
|
|
|
|
|
1999-07-21 07:42:16 +00:00
|
|
|
// See if it's a menu item.
|
1999-07-26 01:35:39 +00:00
|
|
|
if (IsValidItem(current)) {
|
1999-09-21 01:03:00 +00:00
|
|
|
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
|
|
|
|
*aResult = menuFrame.get();
|
|
|
|
NS_IF_ADDREF(*aResult);
|
1999-07-21 07:42:16 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-07-22 01:59:09 +00:00
|
|
|
currFrame = mFrames.GetPrevSiblingFor(currFrame);
|
1999-07-21 07:42:16 +00:00
|
|
|
}
|
|
|
|
|
1999-07-22 01:59:09 +00:00
|
|
|
currFrame = mFrames.LastChild();
|
|
|
|
|
|
|
|
// Still don't have anything. Try cycling from the end.
|
1999-09-21 01:03:00 +00:00
|
|
|
while (currFrame && currFrame != startFrame) {
|
1999-07-21 07:42:16 +00:00
|
|
|
nsCOMPtr<nsIContent> current;
|
1999-07-22 01:59:09 +00:00
|
|
|
currFrame->GetContent(getter_AddRefs(current));
|
1999-07-21 07:42:16 +00:00
|
|
|
|
|
|
|
// See if it's a menu item.
|
1999-07-26 01:35:39 +00:00
|
|
|
if (IsValidItem(current)) {
|
1999-09-21 01:03:00 +00:00
|
|
|
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
|
|
|
|
*aResult = menuFrame.get();
|
|
|
|
NS_IF_ADDREF(*aResult);
|
1999-07-21 07:42:16 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-07-22 01:59:09 +00:00
|
|
|
|
|
|
|
currFrame = mFrames.GetPrevSiblingFor(currFrame);
|
1999-07-21 07:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// No luck. Just return our start value.
|
|
|
|
*aResult = aStart;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-09-21 01:03:00 +00:00
|
|
|
NS_IMETHODIMP nsMenuPopupFrame::SetCurrentMenuItem(nsIMenuFrame* aMenuItem)
|
1999-07-21 07:42:16 +00:00
|
|
|
{
|
|
|
|
if (mCurrentMenu == aMenuItem)
|
|
|
|
return NS_OK;
|
1999-09-21 01:03:00 +00:00
|
|
|
|
1999-07-22 09:01:55 +00:00
|
|
|
// Unset the current child.
|
1999-07-21 08:51:41 +00:00
|
|
|
if (mCurrentMenu) {
|
1999-09-21 01:03:00 +00:00
|
|
|
PRBool isOpen = PR_FALSE;
|
|
|
|
mCurrentMenu->MenuIsOpen(isOpen);
|
1999-09-25 03:39:35 +00:00
|
|
|
mCurrentMenu->SelectMenu(PR_FALSE);
|
1999-09-21 01:03:00 +00:00
|
|
|
if (isOpen)
|
|
|
|
mCurrentMenu->OpenMenu(PR_FALSE);
|
1999-09-25 03:39:35 +00:00
|
|
|
|
1999-07-21 08:51:41 +00:00
|
|
|
}
|
|
|
|
|
1999-07-21 07:42:16 +00:00
|
|
|
// Set the new child.
|
1999-07-21 08:51:41 +00:00
|
|
|
if (aMenuItem) {
|
1999-09-21 01:03:00 +00:00
|
|
|
aMenuItem->SelectMenu(PR_TRUE);
|
1999-07-21 08:51:41 +00:00
|
|
|
}
|
1999-07-22 09:01:55 +00:00
|
|
|
|
1999-07-21 07:42:16 +00:00
|
|
|
mCurrentMenu = aMenuItem;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-07-21 08:51:41 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-26 04:44:41 +00:00
|
|
|
nsMenuPopupFrame::CaptureMouseEvents(nsIPresContext* aPresContext, PRBool aGrabMouseEvents)
|
1999-07-21 08:51:41 +00:00
|
|
|
{
|
|
|
|
// get its view
|
|
|
|
nsIView* view = nsnull;
|
1999-10-26 04:44:41 +00:00
|
|
|
GetView(aPresContext, &view);
|
1999-07-21 08:51:41 +00:00
|
|
|
nsCOMPtr<nsIViewManager> viewMan;
|
|
|
|
PRBool result;
|
|
|
|
|
1999-09-10 08:47:12 +00:00
|
|
|
nsCOMPtr<nsIWidget> widget;
|
|
|
|
|
1999-07-21 08:51:41 +00:00
|
|
|
if (view) {
|
|
|
|
view->GetViewManager(*getter_AddRefs(viewMan));
|
|
|
|
if (viewMan) {
|
1999-09-10 08:47:12 +00:00
|
|
|
view->GetWidget(*getter_AddRefs(widget));
|
1999-07-21 08:51:41 +00:00
|
|
|
if (aGrabMouseEvents) {
|
|
|
|
viewMan->GrabMouseEvents(view,result);
|
|
|
|
mIsCapturingMouseEvents = PR_TRUE;
|
1999-09-21 01:03:00 +00:00
|
|
|
//widget->CaptureMouse(PR_TRUE);
|
1999-07-21 08:51:41 +00:00
|
|
|
} else {
|
|
|
|
viewMan->GrabMouseEvents(nsnull,result);
|
|
|
|
mIsCapturingMouseEvents = PR_FALSE;
|
1999-09-21 01:03:00 +00:00
|
|
|
//widget->CaptureMouse(PR_FALSE);
|
1999-07-21 08:51:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-07-23 07:49:43 +00:00
|
|
|
void
|
1999-07-23 08:36:39 +00:00
|
|
|
nsMenuPopupFrame::Escape(PRBool& aHandledFlag)
|
1999-07-23 07:49:43 +00:00
|
|
|
{
|
1999-07-23 08:36:39 +00:00
|
|
|
if (!mCurrentMenu)
|
|
|
|
return;
|
1999-07-23 07:49:43 +00:00
|
|
|
|
1999-07-23 08:36:39 +00:00
|
|
|
// See if our menu is open.
|
1999-09-21 01:03:00 +00:00
|
|
|
PRBool isOpen = PR_FALSE;
|
|
|
|
mCurrentMenu->MenuIsOpen(isOpen);
|
|
|
|
if (isOpen) {
|
1999-07-23 08:36:39 +00:00
|
|
|
// Let the child menu handle this.
|
1999-09-21 01:03:00 +00:00
|
|
|
mCurrentMenu->Escape(aHandledFlag);
|
1999-07-23 08:36:39 +00:00
|
|
|
if (!aHandledFlag) {
|
|
|
|
// We should close up.
|
1999-09-21 01:03:00 +00:00
|
|
|
mCurrentMenu->OpenMenu(PR_FALSE);
|
1999-07-23 08:36:39 +00:00
|
|
|
aHandledFlag = PR_TRUE;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
1999-07-23 07:49:43 +00:00
|
|
|
}
|
|
|
|
|
1999-07-24 22:02:23 +00:00
|
|
|
void
|
|
|
|
nsMenuPopupFrame::Enter()
|
|
|
|
{
|
|
|
|
// Give it to the child.
|
1999-09-21 01:03:00 +00:00
|
|
|
if (mCurrentMenu)
|
|
|
|
mCurrentMenu->Enter();
|
1999-07-24 22:02:23 +00:00
|
|
|
}
|
|
|
|
|
1999-09-21 01:03:00 +00:00
|
|
|
nsIMenuFrame*
|
1999-07-23 07:49:43 +00:00
|
|
|
nsMenuPopupFrame::FindMenuWithShortcut(PRUint32 aLetter)
|
|
|
|
{
|
|
|
|
// Enumerate over our list of frames.
|
|
|
|
nsIFrame* currFrame = mFrames.FirstChild();
|
|
|
|
while (currFrame) {
|
|
|
|
nsCOMPtr<nsIContent> current;
|
|
|
|
currFrame->GetContent(getter_AddRefs(current));
|
|
|
|
|
|
|
|
// See if it's a menu item.
|
1999-07-26 01:35:39 +00:00
|
|
|
if (IsValidItem(current)) {
|
1999-07-23 07:49:43 +00:00
|
|
|
// Get the shortcut attribute.
|
|
|
|
nsString shortcutKey = "";
|
1999-07-26 01:19:49 +00:00
|
|
|
current->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey, shortcutKey);
|
1999-07-23 07:49:43 +00:00
|
|
|
shortcutKey.ToUpperCase();
|
|
|
|
if (shortcutKey.Length() > 0) {
|
|
|
|
// We've got something.
|
|
|
|
PRUnichar shortcutChar = shortcutKey.CharAt(0);
|
|
|
|
if (shortcutChar == aLetter) {
|
|
|
|
// We match!
|
1999-09-21 01:03:00 +00:00
|
|
|
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
|
|
|
|
if (menuFrame)
|
|
|
|
return menuFrame.get();
|
|
|
|
return nsnull;
|
1999-07-23 07:49:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
currFrame->GetNextSibling(&currFrame);
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
1999-07-23 05:47:43 +00:00
|
|
|
void
|
|
|
|
nsMenuPopupFrame::ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag)
|
|
|
|
{
|
1999-07-23 07:56:27 +00:00
|
|
|
if (mCurrentMenu) {
|
1999-09-21 01:03:00 +00:00
|
|
|
PRBool isOpen = PR_FALSE;
|
|
|
|
mCurrentMenu->MenuIsOpen(isOpen);
|
|
|
|
if (isOpen) {
|
1999-07-23 07:56:27 +00:00
|
|
|
// No way this applies to us. Give it to our child.
|
1999-09-21 01:03:00 +00:00
|
|
|
mCurrentMenu->ShortcutNavigation(aLetter, aHandledFlag);
|
1999-07-23 07:56:27 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// This applies to us. Let's see if one of the shortcuts applies
|
1999-09-21 01:03:00 +00:00
|
|
|
nsIMenuFrame* result = FindMenuWithShortcut(aLetter);
|
1999-07-23 07:56:27 +00:00
|
|
|
if (result) {
|
|
|
|
// We got one!
|
|
|
|
aHandledFlag = PR_TRUE;
|
|
|
|
SetCurrentMenuItem(result);
|
1999-09-21 01:03:00 +00:00
|
|
|
result->OpenMenu(PR_TRUE);
|
|
|
|
result->SelectFirstItem();
|
1999-07-23 07:56:27 +00:00
|
|
|
|
1999-09-21 01:03:00 +00:00
|
|
|
// XXX For menu items, do an execution of the oncommand handler!
|
|
|
|
// Still needed or did I do this already? I'm going senile. - Dave
|
1999-07-23 07:56:27 +00:00
|
|
|
}
|
1999-07-23 05:47:43 +00:00
|
|
|
}
|
|
|
|
|
1999-07-22 09:01:55 +00:00
|
|
|
void
|
|
|
|
nsMenuPopupFrame::KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag)
|
|
|
|
{
|
|
|
|
// This method only gets called if we're open.
|
1999-07-26 06:29:48 +00:00
|
|
|
if (!mCurrentMenu && (aDirection == NS_VK_RIGHT || aDirection == NS_VK_LEFT)) {
|
1999-07-22 09:01:55 +00:00
|
|
|
// We've been opened, but we haven't had anything selected.
|
1999-07-26 06:29:48 +00:00
|
|
|
// We can handle RIGHT, but our parent handles LEFT.
|
|
|
|
if (aDirection == NS_VK_RIGHT) {
|
1999-09-21 01:03:00 +00:00
|
|
|
nsIMenuFrame* nextItem;
|
1999-07-26 06:29:48 +00:00
|
|
|
GetNextMenuItem(nsnull, &nextItem);
|
|
|
|
if (nextItem) {
|
|
|
|
aHandledFlag = PR_TRUE;
|
|
|
|
SetCurrentMenuItem(nextItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
1999-07-22 09:01:55 +00:00
|
|
|
}
|
|
|
|
|
1999-09-21 01:03:00 +00:00
|
|
|
PRBool isContainer = PR_FALSE;
|
|
|
|
PRBool isOpen = PR_FALSE;
|
|
|
|
if (mCurrentMenu) {
|
|
|
|
mCurrentMenu->MenuIsContainer(isContainer);
|
|
|
|
mCurrentMenu->MenuIsOpen(isOpen);
|
|
|
|
|
|
|
|
if (isOpen) {
|
1999-07-25 00:16:11 +00:00
|
|
|
// Give our child a shot.
|
1999-09-21 01:03:00 +00:00
|
|
|
mCurrentMenu->KeyboardNavigation(aDirection, aHandledFlag);
|
1999-07-25 00:16:11 +00:00
|
|
|
}
|
1999-09-21 01:03:00 +00:00
|
|
|
else if (aDirection == NS_VK_RIGHT && isContainer) {
|
1999-07-25 00:16:11 +00:00
|
|
|
// The menu is not yet open. Open it and select the first item.
|
|
|
|
aHandledFlag = PR_TRUE;
|
1999-09-21 01:03:00 +00:00
|
|
|
mCurrentMenu->OpenMenu(PR_TRUE);
|
|
|
|
mCurrentMenu->SelectFirstItem();
|
1999-07-25 00:16:11 +00:00
|
|
|
}
|
1999-07-22 09:01:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (aHandledFlag)
|
|
|
|
return; // The child menu took it for us.
|
|
|
|
|
|
|
|
// For the vertical direction, we can move up or down.
|
|
|
|
if (aDirection == NS_VK_UP || aDirection == NS_VK_DOWN) {
|
|
|
|
|
1999-09-21 01:03:00 +00:00
|
|
|
nsIMenuFrame* nextItem;
|
1999-07-22 09:01:55 +00:00
|
|
|
|
|
|
|
if (aDirection == NS_VK_DOWN)
|
|
|
|
GetNextMenuItem(mCurrentMenu, &nextItem);
|
|
|
|
else GetPreviousMenuItem(mCurrentMenu, &nextItem);
|
|
|
|
|
|
|
|
SetCurrentMenuItem(nextItem);
|
|
|
|
|
|
|
|
aHandledFlag = PR_TRUE;
|
|
|
|
}
|
1999-09-21 01:03:00 +00:00
|
|
|
else if (mCurrentMenu && isContainer && isOpen) {
|
1999-07-26 04:38:28 +00:00
|
|
|
if (aDirection == NS_VK_LEFT) {
|
|
|
|
// Close it up.
|
1999-09-21 01:03:00 +00:00
|
|
|
mCurrentMenu->OpenMenu(PR_FALSE);
|
1999-07-26 06:29:48 +00:00
|
|
|
aHandledFlag = PR_TRUE;
|
1999-07-26 04:38:28 +00:00
|
|
|
}
|
1999-07-25 01:14:43 +00:00
|
|
|
}
|
1999-07-24 01:59:32 +00:00
|
|
|
}
|
|
|
|
|
1999-09-21 01:03:00 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsMenuPopupFrame::GetParentPopup(nsIMenuParent** aMenuParent)
|
|
|
|
{
|
|
|
|
*aMenuParent = nsnull;
|
|
|
|
nsIFrame* frame;
|
|
|
|
GetParent(&frame);
|
|
|
|
if (frame) {
|
|
|
|
nsIFrame* grandparent;
|
|
|
|
frame->GetParent(&grandparent);
|
|
|
|
if (grandparent) {
|
|
|
|
nsCOMPtr<nsIMenuParent> menuParent = do_QueryInterface(grandparent);
|
|
|
|
if (menuParent) {
|
|
|
|
*aMenuParent = menuParent.get();
|
|
|
|
NS_ADDREF(*aMenuParent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-08-12 20:45:47 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsMenuPopupFrame::HideChain()
|
|
|
|
{
|
1999-10-05 23:31:06 +00:00
|
|
|
// Stop capturing rollups
|
|
|
|
// (must do this during Hide, which happens before the menu item is executed,
|
|
|
|
// since this reinstates normal event handling.)
|
|
|
|
if (nsMenuFrame::mDismissalListener)
|
|
|
|
nsMenuFrame::mDismissalListener->Unregister();
|
|
|
|
|
1999-08-12 20:45:47 +00:00
|
|
|
nsIFrame* frame;
|
|
|
|
GetParent(&frame);
|
|
|
|
if (frame) {
|
1999-09-21 01:03:00 +00:00
|
|
|
nsCOMPtr<nsIPopupSetFrame> popupSetFrame = do_QueryInterface(frame);
|
|
|
|
if (popupSetFrame) {
|
|
|
|
// Destroy the popup.
|
|
|
|
popupSetFrame->HidePopup();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(frame);
|
|
|
|
if (!menuFrame)
|
|
|
|
return NS_OK;
|
|
|
|
|
1999-08-12 20:45:47 +00:00
|
|
|
menuFrame->ActivateMenu(PR_FALSE);
|
|
|
|
menuFrame->SelectMenu(PR_FALSE);
|
|
|
|
|
|
|
|
// Get the parent.
|
|
|
|
nsCOMPtr<nsIMenuParent> menuParent;
|
|
|
|
menuFrame->GetMenuParent(getter_AddRefs(menuParent));
|
|
|
|
if (menuParent)
|
|
|
|
menuParent->HideChain();
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-07-24 01:59:32 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsMenuPopupFrame::DismissChain()
|
|
|
|
{
|
1999-09-25 03:39:35 +00:00
|
|
|
// Stop capturing rollups
|
|
|
|
if (nsMenuFrame::mDismissalListener)
|
|
|
|
nsMenuFrame::mDismissalListener->Unregister();
|
|
|
|
|
1999-07-24 01:59:32 +00:00
|
|
|
// Get our menu parent.
|
|
|
|
nsIFrame* frame;
|
|
|
|
GetParent(&frame);
|
|
|
|
if (frame) {
|
1999-09-21 01:03:00 +00:00
|
|
|
nsCOMPtr<nsIPopupSetFrame> popupSetFrame = do_QueryInterface(frame);
|
|
|
|
if (popupSetFrame) {
|
|
|
|
// Destroy the popup.
|
|
|
|
popupSetFrame->DestroyPopup();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(frame);
|
|
|
|
if (!menuFrame)
|
|
|
|
return NS_OK;
|
|
|
|
|
1999-07-24 01:59:32 +00:00
|
|
|
menuFrame->OpenMenu(PR_FALSE);
|
|
|
|
|
|
|
|
// Get the parent.
|
|
|
|
nsCOMPtr<nsIMenuParent> menuParent;
|
|
|
|
menuFrame->GetMenuParent(getter_AddRefs(menuParent));
|
|
|
|
if (menuParent)
|
|
|
|
menuParent->DismissChain();
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-07-26 01:35:39 +00:00
|
|
|
|
1999-09-25 03:39:35 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsMenuPopupFrame::GetWidget(nsIWidget **aWidget)
|
|
|
|
{
|
|
|
|
// Get parent view
|
|
|
|
nsIView * view = nsnull;
|
1999-10-26 04:44:41 +00:00
|
|
|
nsMenuPopupFrame::GetNearestEnclosingView(mPresContext, this, &view);
|
1999-09-25 03:39:35 +00:00
|
|
|
if (!view)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
view->GetWidget(*aWidget);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-09-21 01:03:00 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsMenuPopupFrame::CreateDismissalListener()
|
|
|
|
{
|
1999-10-04 02:27:09 +00:00
|
|
|
nsMenuDismissalListener *listener = new nsMenuDismissalListener();
|
|
|
|
if (!listener) return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
nsMenuFrame::mDismissalListener = listener;
|
|
|
|
NS_ADDREF(listener);
|
1999-09-21 01:03:00 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-07-26 01:35:39 +00:00
|
|
|
PRBool
|
|
|
|
nsMenuPopupFrame::IsValidItem(nsIContent* aContent)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
1999-07-31 11:29:03 +00:00
|
|
|
if (tag && (tag.get() == nsXULAtoms::menu ||
|
|
|
|
tag.get() == nsXULAtoms::menuitem) &&
|
1999-07-26 01:35:39 +00:00
|
|
|
!IsDisabled(aContent))
|
|
|
|
return PR_TRUE;
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsMenuPopupFrame::IsDisabled(nsIContent* aContent)
|
|
|
|
{
|
|
|
|
nsString disabled = "";
|
|
|
|
aContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::disabled, disabled);
|
|
|
|
if (disabled == "true")
|
|
|
|
return PR_TRUE;
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
1999-09-10 08:47:12 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsMenuPopupFrame::HandleEvent(nsIPresContext* aPresContext,
|
1999-09-10 08:47:12 +00:00
|
|
|
nsGUIEvent* aEvent,
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStatus* aEventStatus)
|
1999-09-10 08:47:12 +00:00
|
|
|
{
|
1999-09-21 01:03:00 +00:00
|
|
|
return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
1999-09-10 08:47:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsMenuPopupFrame::Destroy(nsIPresContext* aPresContext)
|
1999-09-10 08:47:12 +00:00
|
|
|
{
|
1999-09-21 01:03:00 +00:00
|
|
|
//nsCOMPtr<nsIDOMEventReceiver> target = do_QueryInterface(mContent);
|
|
|
|
//target->RemoveEventListener("mousemove", mMenuPopupEntryListener, PR_TRUE);
|
|
|
|
return nsBoxFrame::Destroy(aPresContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-26 04:44:41 +00:00
|
|
|
nsMenuPopupFrame::GetFrameForPoint(nsIPresContext* aPresContext,
|
|
|
|
const nsPoint& aPoint,
|
|
|
|
nsIFrame** aFrame)
|
1999-09-21 01:03:00 +00:00
|
|
|
{
|
|
|
|
nsRect rect;
|
|
|
|
GetRect(rect);
|
|
|
|
if (rect.Contains(aPoint)) {
|
1999-10-26 04:44:41 +00:00
|
|
|
return nsBoxFrame::GetFrameForPoint(aPresContext, aPoint, aFrame);
|
1999-09-21 01:03:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*aFrame = this;
|
1999-09-10 08:47:12 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|