Add implementation for MoveTo method to nsMenuPopupFrame (exposed through nsIPopupBoxObject), etc.
Also change static mDismissalListener to sDismissalListener. Part of fix for 95401 r=jag, sr=hyatt git-svn-id: svn://10.0.0.236/trunk@102637 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -522,8 +522,8 @@ nsMenuBarFrame::Escape(PRBool& aHandledFlag)
|
||||
// designation.
|
||||
mCurrentMenu->OpenMenu(PR_FALSE);
|
||||
}
|
||||
if (nsMenuFrame::mDismissalListener)
|
||||
nsMenuFrame::mDismissalListener->Unregister();
|
||||
if (nsMenuFrame::sDismissalListener)
|
||||
nsMenuFrame::sDismissalListener->Unregister();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -537,8 +537,8 @@ nsMenuBarFrame::Escape(PRBool& aHandledFlag)
|
||||
RemoveKeyboardNavigator();
|
||||
|
||||
// Clear out our dismissal listener
|
||||
if (nsMenuFrame::mDismissalListener)
|
||||
nsMenuFrame::mDismissalListener->Unregister();
|
||||
if (nsMenuFrame::sDismissalListener)
|
||||
nsMenuFrame::sDismissalListener->Unregister();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -571,8 +571,8 @@ nsMenuBarFrame::HideChain()
|
||||
// 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();
|
||||
if (nsMenuFrame::sDismissalListener)
|
||||
nsMenuFrame::sDismissalListener->Unregister();
|
||||
|
||||
if (mCurrentMenu) {
|
||||
mCurrentMenu->ActivateMenu(PR_FALSE);
|
||||
@@ -585,8 +585,8 @@ NS_IMETHODIMP
|
||||
nsMenuBarFrame::DismissChain()
|
||||
{
|
||||
// Stop capturing rollups
|
||||
if (nsMenuFrame::mDismissalListener)
|
||||
nsMenuFrame::mDismissalListener->Unregister();
|
||||
if (nsMenuFrame::sDismissalListener)
|
||||
nsMenuFrame::sDismissalListener->Unregister();
|
||||
|
||||
SetCurrentMenuItem(nsnull);
|
||||
SetActive(PR_FALSE);
|
||||
@@ -629,7 +629,7 @@ nsMenuBarFrame::GetWidget(nsIWidget **aWidget)
|
||||
NS_IMETHODIMP
|
||||
nsMenuBarFrame::CreateDismissalListener()
|
||||
{
|
||||
NS_ADDREF(nsMenuFrame::mDismissalListener = new nsMenuDismissalListener());
|
||||
NS_ADDREF(nsMenuFrame::sDismissalListener = new nsMenuDismissalListener());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ nsMenuDismissalListener::SetCurrentMenuParent(nsIMenuParent* aMenuParent)
|
||||
widget->CaptureRollupEvents(this, PR_TRUE, PR_TRUE);
|
||||
mWidget = widget;
|
||||
|
||||
NS_ADDREF(nsMenuFrame::mDismissalListener = this);
|
||||
NS_ADDREF(nsMenuFrame::sDismissalListener = this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@@ -172,7 +172,7 @@ nsMenuDismissalListener::Unregister()
|
||||
mWidget = nsnull;
|
||||
}
|
||||
|
||||
NS_RELEASE(nsMenuFrame::mDismissalListener);
|
||||
NS_RELEASE(nsMenuFrame::sDismissalListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
|
||||
static PRInt32 gEatMouseMove = PR_FALSE;
|
||||
|
||||
nsMenuDismissalListener* nsMenuFrame::mDismissalListener = nsnull;
|
||||
nsMenuDismissalListener* nsMenuFrame::sDismissalListener = nsnull;
|
||||
|
||||
static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
||||
|
||||
@@ -691,8 +691,8 @@ nsMenuFrame::OpenMenuInternal(PRBool aActivateFlag)
|
||||
mCreateHandlerSucceeded = PR_TRUE;
|
||||
|
||||
// Set the focus back to our view's widget.
|
||||
if (nsMenuFrame::mDismissalListener)
|
||||
nsMenuFrame::mDismissalListener->EnableListener(PR_FALSE);
|
||||
if (nsMenuFrame::sDismissalListener)
|
||||
nsMenuFrame::sDismissalListener->EnableListener(PR_FALSE);
|
||||
|
||||
// XXX Only have this here because of RDF-generated content.
|
||||
MarkAsGenerated();
|
||||
@@ -788,8 +788,8 @@ nsMenuFrame::OpenMenuInternal(PRBool aActivateFlag)
|
||||
}
|
||||
|
||||
// Set the focus back to our view's widget.
|
||||
if (nsMenuFrame::mDismissalListener)
|
||||
nsMenuFrame::mDismissalListener->EnableListener(PR_TRUE);
|
||||
if (nsMenuFrame::sDismissalListener)
|
||||
nsMenuFrame::sDismissalListener->EnableListener(PR_TRUE);
|
||||
|
||||
}
|
||||
else {
|
||||
@@ -802,9 +802,9 @@ nsMenuFrame::OpenMenuInternal(PRBool aActivateFlag)
|
||||
mMenuOpen = PR_FALSE;
|
||||
|
||||
// Set the focus back to our view's widget.
|
||||
if (nsMenuFrame::mDismissalListener) {
|
||||
nsMenuFrame::mDismissalListener->EnableListener(PR_FALSE);
|
||||
nsMenuFrame::mDismissalListener->SetCurrentMenuParent(mMenuParent);
|
||||
if (nsMenuFrame::sDismissalListener) {
|
||||
nsMenuFrame::sDismissalListener->EnableListener(PR_FALSE);
|
||||
nsMenuFrame::sDismissalListener->SetCurrentMenuParent(mMenuParent);
|
||||
}
|
||||
|
||||
nsIFrame* frame = mPopupFrames.FirstChild();
|
||||
@@ -830,8 +830,8 @@ nsMenuFrame::OpenMenuInternal(PRBool aActivateFlag)
|
||||
|
||||
OnDestroyed();
|
||||
|
||||
if (nsMenuFrame::mDismissalListener)
|
||||
nsMenuFrame::mDismissalListener->EnableListener(PR_TRUE);
|
||||
if (nsMenuFrame::sDismissalListener)
|
||||
nsMenuFrame::sDismissalListener->EnableListener(PR_TRUE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1486,8 +1486,8 @@ nsMenuFrame::Execute()
|
||||
// Temporarily disable rollup events on this menu. This is
|
||||
// to suppress this menu getting removed in the case where
|
||||
// the oncommand handler opens a dialog, etc.
|
||||
if ( nsMenuFrame::mDismissalListener ) {
|
||||
nsMenuFrame::mDismissalListener->EnableListener(PR_FALSE);
|
||||
if ( nsMenuFrame::sDismissalListener ) {
|
||||
nsMenuFrame::sDismissalListener->EnableListener(PR_FALSE);
|
||||
}
|
||||
|
||||
// Get our own content node and hold on to it to keep it from going away.
|
||||
@@ -1555,8 +1555,8 @@ nsMenuFrame::Execute()
|
||||
// END HACK
|
||||
|
||||
// Re-enable rollup events on this menu.
|
||||
if ( nsMenuFrame::mDismissalListener ) {
|
||||
nsMenuFrame::mDismissalListener->EnableListener(PR_TRUE);
|
||||
if ( nsMenuFrame::sDismissalListener ) {
|
||||
nsMenuFrame::sDismissalListener->EnableListener(PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1841,7 +1841,7 @@ nsMenuFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
void
|
||||
nsMenuFrame::UpdateDismissalListener(nsIMenuParent* aMenuParent)
|
||||
{
|
||||
if (!nsMenuFrame::mDismissalListener) {
|
||||
if (!nsMenuFrame::sDismissalListener) {
|
||||
if (!aMenuParent)
|
||||
return;
|
||||
// Create the listener and attach it to the outermost window.
|
||||
@@ -1850,7 +1850,7 @@ nsMenuFrame::UpdateDismissalListener(nsIMenuParent* aMenuParent)
|
||||
|
||||
// Make sure the menu dismissal listener knows what the current
|
||||
// innermost menu popup frame is.
|
||||
nsMenuFrame::mDismissalListener->SetCurrentMenuParent(aMenuParent);
|
||||
nsMenuFrame::sDismissalListener->SetCurrentMenuParent(aMenuParent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
||||
@@ -236,7 +236,7 @@ protected:
|
||||
static nsString *gModifierSeparator;
|
||||
|
||||
public:
|
||||
static nsMenuDismissalListener* mDismissalListener; // The listener that dismisses menus.
|
||||
static nsMenuDismissalListener* sDismissalListener; // The listener that dismisses menus.
|
||||
private:
|
||||
nsCSSFrameConstructor* mFrameConstructor;
|
||||
}; // class nsMenuFrame
|
||||
|
||||
@@ -133,7 +133,7 @@ NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
|
||||
//
|
||||
nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell)
|
||||
:nsBoxFrame(aShell), mCurrentMenu(nsnull), mTimerMenu(nsnull), mCloseTimer(nsnull),
|
||||
mMenuCanOverlapOSBar(PR_FALSE)
|
||||
mMenuCanOverlapOSBar(PR_FALSE), mShouldAutoPosition(PR_TRUE), mShouldRollup(PR_TRUE)
|
||||
{
|
||||
SetIsContextMenu(PR_FALSE); // we're not a context menu by default
|
||||
// Don't allow container frames to automatically position
|
||||
@@ -216,6 +216,8 @@ nsMenuPopupFrame::Init(nsIPresContext* aPresContext,
|
||||
ourView->CreateWidget(kCChildCID, &widgetData, nsnull);
|
||||
#endif
|
||||
|
||||
MoveToAttributePosition();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -529,7 +531,7 @@ void GetWidgetForView(nsIView *aView, nsIWidget *&aWidget)
|
||||
// this document.
|
||||
//
|
||||
void
|
||||
nsMenuPopupFrame :: AdjustClientXYForNestedDocuments ( nsIDOMXULDocument* inPopupDoc, nsIPresShell* inPopupShell,
|
||||
nsMenuPopupFrame::AdjustClientXYForNestedDocuments ( nsIDOMXULDocument* inPopupDoc, nsIPresShell* inPopupShell,
|
||||
PRInt32 inClientX, PRInt32 inClientY,
|
||||
PRInt32* outAdjX, PRInt32* outAdjY )
|
||||
{
|
||||
@@ -607,7 +609,7 @@ nsMenuPopupFrame :: AdjustClientXYForNestedDocuments ( nsIDOMXULDocument* inPopu
|
||||
// the parent.
|
||||
//
|
||||
void
|
||||
nsMenuPopupFrame :: AdjustPositionForAnchorAlign ( PRInt32* ioXPos, PRInt32* ioYPos, const nsRect & inParentRect,
|
||||
nsMenuPopupFrame::AdjustPositionForAnchorAlign ( PRInt32* ioXPos, PRInt32* ioYPos, const nsRect & inParentRect,
|
||||
const nsString& aPopupAnchor, const nsString& aPopupAlign,
|
||||
PRBool* outFlushWithTopBottom )
|
||||
{
|
||||
@@ -684,7 +686,7 @@ nsMenuPopupFrame :: AdjustPositionForAnchorAlign ( PRInt32* ioXPos, PRInt32* ioY
|
||||
// flush against the bottom, is there more room if its bottom edge were flush against the top)
|
||||
//
|
||||
PRBool
|
||||
nsMenuPopupFrame :: IsMoreRoomOnOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32 inScreenViewLocX, PRInt32 inScreenViewLocY,
|
||||
nsMenuPopupFrame::IsMoreRoomOnOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32 inScreenViewLocX, PRInt32 inScreenViewLocY,
|
||||
const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips,
|
||||
PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips )
|
||||
{
|
||||
@@ -722,10 +724,10 @@ nsMenuPopupFrame :: IsMoreRoomOnOtherSideOfParent ( PRBool inFlushAboveBelow, PR
|
||||
// have the side effect of touching |mRect|.
|
||||
//
|
||||
void
|
||||
nsMenuPopupFrame :: MovePopupToOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32* ioXPos, PRInt32* ioYPos,
|
||||
PRInt32* ioScreenViewLocX, PRInt32* ioScreenViewLocY,
|
||||
const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips,
|
||||
PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips )
|
||||
nsMenuPopupFrame::MovePopupToOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32* ioXPos, PRInt32* ioYPos,
|
||||
PRInt32* ioScreenViewLocX, PRInt32* ioScreenViewLocY,
|
||||
const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips,
|
||||
PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips )
|
||||
{
|
||||
if ( inFlushAboveBelow ) {
|
||||
if ( *ioScreenViewLocY > inScreenParentFrameRect.y ) { // view is currently below parent
|
||||
@@ -784,6 +786,9 @@ nsMenuPopupFrame::SyncViewWithFrame(nsIPresContext* aPresContext,
|
||||
NS_ENSURE_ARG(aPresContext);
|
||||
NS_ENSURE_ARG(aFrame);
|
||||
|
||||
if (!mShouldAutoPosition)
|
||||
return NS_OK;
|
||||
|
||||
// |containingView|
|
||||
// The view that contains the frame that is invoking this popup. This is
|
||||
// the canvas view inside the scrollport view. It can have negative bounds
|
||||
@@ -1541,11 +1546,14 @@ nsMenuPopupFrame::GetParentPopup(nsIMenuParent** aMenuParent)
|
||||
NS_IMETHODIMP
|
||||
nsMenuPopupFrame::HideChain()
|
||||
{
|
||||
if (!mShouldRollup)
|
||||
return NS_OK;
|
||||
|
||||
// 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();
|
||||
if (nsMenuFrame::sDismissalListener)
|
||||
nsMenuFrame::sDismissalListener->Unregister();
|
||||
|
||||
nsIFrame* frame;
|
||||
GetParent(&frame);
|
||||
@@ -1575,9 +1583,12 @@ nsMenuPopupFrame::HideChain()
|
||||
NS_IMETHODIMP
|
||||
nsMenuPopupFrame::DismissChain()
|
||||
{
|
||||
if (!mShouldRollup)
|
||||
return NS_OK;
|
||||
|
||||
// Stop capturing rollups
|
||||
if (nsMenuFrame::mDismissalListener)
|
||||
nsMenuFrame::mDismissalListener->Unregister();
|
||||
if (nsMenuFrame::sDismissalListener)
|
||||
nsMenuFrame::sDismissalListener->Unregister();
|
||||
|
||||
// Get our menu parent.
|
||||
nsIFrame* frame;
|
||||
@@ -1622,7 +1633,7 @@ nsMenuPopupFrame::CreateDismissalListener()
|
||||
{
|
||||
nsMenuDismissalListener *listener = new nsMenuDismissalListener();
|
||||
if (!listener) return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsMenuFrame::mDismissalListener = listener;
|
||||
nsMenuFrame::sDismissalListener = listener;
|
||||
NS_ADDREF(listener);
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1687,6 +1698,43 @@ nsMenuPopupFrame::IsDisabled(nsIContent* aContent)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuPopupFrame::AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType,
|
||||
PRInt32 aHint)
|
||||
|
||||
{
|
||||
nsresult rv = nsBoxFrame::AttributeChanged(aPresContext, aChild,
|
||||
aNameSpaceID, aAttribute, aModType, aHint);
|
||||
|
||||
if (aAttribute == nsXULAtoms::left || aAttribute == nsXULAtoms::top)
|
||||
MoveToAttributePosition();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuPopupFrame::MoveToAttributePosition()
|
||||
{
|
||||
// Move the widget around when the user sets the |left| and |top| attributes.
|
||||
// Note that this is not the best way to move the widget, as it results in lots
|
||||
// of FE notifications and is likely to be slow as molasses. Use |moveTo| on
|
||||
// nsIPopupBoxObject if possible.
|
||||
nsAutoString left, top;
|
||||
mContent->GetAttr(kNameSpaceID_None, nsXULAtoms::left, left);
|
||||
mContent->GetAttr(kNameSpaceID_None, nsXULAtoms::top, top);
|
||||
PRInt32 err1, err2, xPos, yPos;
|
||||
xPos = left.ToInteger(&err1);
|
||||
yPos = top.ToInteger(&err2);
|
||||
|
||||
if (NS_SUCCEEDED(err1) && NS_SUCCEEDED(err2))
|
||||
MoveTo(xPos, yPos);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuPopupFrame::HandleEvent(nsIPresContext* aPresContext,
|
||||
nsGUIEvent* aEvent,
|
||||
@@ -1829,9 +1877,92 @@ nsMenuPopupFrame::KillCloseTimer()
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuPopupFrame :: KillPendingTimers ( )
|
||||
nsMenuPopupFrame::KillPendingTimers ( )
|
||||
{
|
||||
return KillCloseTimer();
|
||||
|
||||
} // KillPendingTimers
|
||||
|
||||
void
|
||||
nsMenuPopupFrame::MoveTo(PRInt32 aLeft, PRInt32 aTop)
|
||||
{
|
||||
// Set the 'left' and 'top' attributes
|
||||
nsAutoString left, top;
|
||||
left.AppendInt(aLeft);
|
||||
top.AppendInt(aTop);
|
||||
|
||||
mContent->SetAttr(kNameSpaceID_None, nsXULAtoms::left, left, PR_FALSE);
|
||||
mContent->SetAttr(kNameSpaceID_None, nsXULAtoms::top, top, PR_FALSE);
|
||||
|
||||
nsIView* view = nsnull;
|
||||
GetView(mPresContext, &view);
|
||||
|
||||
// Retrieve screen position of parent view
|
||||
nsIView* parentView = nsnull;
|
||||
view->GetParent(parentView);
|
||||
nsPoint screenPos;
|
||||
GetScreenPosition(parentView, screenPos);
|
||||
|
||||
// Move the widget
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
view->GetWidget(*getter_AddRefs(widget));
|
||||
widget->Move(aLeft - screenPos.x, aTop - screenPos.y);
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuPopupFrame::GetScreenPosition(nsIView* aView, nsPoint& aScreenPosition)
|
||||
{
|
||||
nsPoint screenPos(0,0);
|
||||
nscoord x, y;
|
||||
|
||||
nsIView* currView = aView;
|
||||
nsIView* nextView = nsnull;
|
||||
|
||||
while (1) {
|
||||
currView->GetPosition(&x, &y);
|
||||
screenPos.x += x;
|
||||
screenPos.y += y;
|
||||
|
||||
currView->GetParent(nextView);
|
||||
if (!nextView)
|
||||
break;
|
||||
else
|
||||
currView = nextView;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWidget> rootWidget;
|
||||
currView->GetWidget(*getter_AddRefs(rootWidget));
|
||||
nsRect bounds, screenBounds;
|
||||
rootWidget->GetScreenBounds(bounds);
|
||||
rootWidget->WidgetToScreen(bounds, screenBounds);
|
||||
|
||||
float t2p;
|
||||
mPresContext->GetTwipsToPixels(&t2p);
|
||||
|
||||
aScreenPosition.x = NSTwipsToIntPixels(screenPos.x, t2p) + screenBounds.x;
|
||||
aScreenPosition.y = NSTwipsToIntPixels(screenPos.y, t2p) + screenBounds.y;
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuPopupFrame::GetAutoPosition(PRBool* aShouldAutoPosition)
|
||||
{
|
||||
*aShouldAutoPosition = mShouldAutoPosition;
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuPopupFrame::SetAutoPosition(PRBool aShouldAutoPosition)
|
||||
{
|
||||
mShouldAutoPosition = aShouldAutoPosition;
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuPopupFrame::EnableRollup(PRBool aShouldRollup)
|
||||
{
|
||||
if (!aShouldRollup) {
|
||||
if (nsMenuFrame::sDismissalListener)
|
||||
nsMenuFrame::sDismissalListener->Unregister();
|
||||
}
|
||||
else
|
||||
CreateDismissalListener();
|
||||
}
|
||||
|
||||
|
||||
@@ -94,10 +94,17 @@ public:
|
||||
|
||||
// Overridden methods
|
||||
NS_IMETHOD Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType,
|
||||
PRInt32 aHint);
|
||||
|
||||
NS_IMETHOD HandleEvent(nsIPresContext* aPresContext,
|
||||
nsGUIEvent* aEvent,
|
||||
@@ -142,6 +149,13 @@ public:
|
||||
|
||||
void EnsureMenuItemIsVisible(nsIMenuFrame* aMenuFrame);
|
||||
|
||||
void MoveTo(PRInt32 aLeft, PRInt32 aTop);
|
||||
void GetScreenPosition(nsIView* aView, nsPoint& aScreenPosition);
|
||||
|
||||
void GetAutoPosition(PRBool* aShouldAutoPosition);
|
||||
void SetAutoPosition(PRBool aShouldAutoPosition);
|
||||
void EnableRollup(PRBool aShouldRollup);
|
||||
|
||||
nsIScrollableView* GetScrollableView(nsIFrame* aStart);
|
||||
|
||||
protected:
|
||||
@@ -167,6 +181,10 @@ protected:
|
||||
const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips,
|
||||
PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips ) ;
|
||||
|
||||
// Move the popup to the position specified in its |left| and |top| attributes.
|
||||
void MoveToAttributePosition();
|
||||
|
||||
|
||||
nsIMenuFrame* mCurrentMenu; // The current menu that is active.
|
||||
PRBool mIsCapturingMouseEvents; // Whether or not we're grabbing the mouse events.
|
||||
// XXX Hack
|
||||
@@ -182,6 +200,9 @@ protected:
|
||||
|
||||
PRBool mMenuCanOverlapOSBar; // can we appear over the taskbar/menubar?
|
||||
|
||||
PRBool mShouldAutoPosition; // Should SyncViewWithFrame be allowed to auto position popup?
|
||||
PRBool mShouldRollup; // Should this menupopup be allowed to dismiss automatically?
|
||||
|
||||
}; // class nsMenuPopupFrame
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
* Original Authors:
|
||||
* David W. Hyatt <hyatt@netscape.com>
|
||||
* Ben Goodger <ben@netscape.com>
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
@@ -32,6 +34,13 @@
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsXULAtoms.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
|
||||
class nsPopupBoxObject : public nsIPopupBoxObject, public nsBoxObject
|
||||
{
|
||||
@@ -41,8 +50,7 @@ public:
|
||||
|
||||
nsPopupBoxObject();
|
||||
virtual ~nsPopupBoxObject();
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
/* Implementation file */
|
||||
@@ -151,8 +159,112 @@ nsPopupBoxObject::ShowPopup(nsIDOMElement* aSrcContent,
|
||||
nsAutoString anchorAlign(anAnchorAlignment);
|
||||
nsAutoString popupAlign(aPopupAlignment);
|
||||
|
||||
return popupSet->ShowPopup(srcContent, popupContent, aXPos, aYPos, popupType, anchorAlign,
|
||||
popupAlign);
|
||||
// Use |left| and |top| dimension attributes to position the popup if
|
||||
// present, as they may have been persisted.
|
||||
nsAutoString left, top;
|
||||
popupContent->GetAttr(kNameSpaceID_None, nsXULAtoms::left, left);
|
||||
popupContent->GetAttr(kNameSpaceID_None, nsXULAtoms::top, top);
|
||||
|
||||
PRInt32 err;
|
||||
if (!left.IsEmpty()) {
|
||||
aXPos = left.ToInteger(&err);
|
||||
if (NS_FAILED(err))
|
||||
return err;
|
||||
}
|
||||
if (!top.IsEmpty()) {
|
||||
aYPos = top.ToInteger(&err);
|
||||
if (NS_FAILED(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
return popupSet->ShowPopup(srcContent, popupContent, aXPos, aYPos,
|
||||
popupType, anchorAlign, popupAlign);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPopupBoxObject::MoveTo(PRInt32 aLeft, PRInt32 aTop)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame) return NS_OK;
|
||||
|
||||
nsMenuPopupFrame* menuPopupFrame = NS_STATIC_CAST(nsMenuPopupFrame*, frame);
|
||||
if (!menuPopupFrame) return NS_OK;
|
||||
|
||||
menuPopupFrame->MoveTo(aLeft, aTop);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPopupBoxObject::SizeTo(PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
nsAutoString width, height;
|
||||
width.AppendInt(aWidth);
|
||||
height.AppendInt(aHeight);
|
||||
|
||||
mContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::width, width, PR_FALSE);
|
||||
mContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::height, height, PR_TRUE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPopupBoxObject::GetAutoPosition(PRBool* aShouldAutoPosition)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame) return NS_OK;
|
||||
|
||||
nsMenuPopupFrame* menuPopupFrame = NS_STATIC_CAST(nsMenuPopupFrame*, frame);
|
||||
if (!menuPopupFrame) return NS_OK;
|
||||
|
||||
menuPopupFrame->GetAutoPosition(aShouldAutoPosition);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPopupBoxObject::SetAutoPosition(PRBool aShouldAutoPosition)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame) return NS_OK;
|
||||
|
||||
nsMenuPopupFrame* menuPopupFrame = NS_STATIC_CAST(nsMenuPopupFrame*, frame);
|
||||
if (!menuPopupFrame) return NS_OK;
|
||||
|
||||
menuPopupFrame->SetAutoPosition(aShouldAutoPosition);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPopupBoxObject::EnableRollup(PRBool aShouldRollup)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame) return NS_OK;
|
||||
|
||||
nsMenuPopupFrame* menuPopupFrame = NS_STATIC_CAST(nsMenuPopupFrame*, frame);
|
||||
if (!menuPopupFrame) return NS_OK;
|
||||
|
||||
menuPopupFrame->EnableRollup(aShouldRollup);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPopupBoxObject::EnableKeyboardNavigator(PRBool aEnableKeyboardNavigator)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame) return NS_OK;
|
||||
|
||||
nsMenuPopupFrame* menuPopupFrame = NS_STATIC_CAST(nsMenuPopupFrame*, frame);
|
||||
if (!menuPopupFrame) return NS_OK;
|
||||
|
||||
if (aEnableKeyboardNavigator)
|
||||
menuPopupFrame->InstallKeyboardNavigator();
|
||||
else
|
||||
menuPopupFrame->RemoveKeyboardNavigator();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -444,8 +444,8 @@ nsPopupSetFrame::OpenPopup(nsPopupFrameList* aEntry, PRBool aActivateFlag)
|
||||
|
||||
// Unregister, but not if we're a tooltip
|
||||
if (aEntry->mPopupType != NS_LITERAL_STRING("tooltip") ) {
|
||||
if (nsMenuFrame::mDismissalListener)
|
||||
nsMenuFrame::mDismissalListener->Unregister();
|
||||
if (nsMenuFrame::sDismissalListener)
|
||||
nsMenuFrame::sDismissalListener->Unregister();
|
||||
}
|
||||
|
||||
// Remove any keyboard navigators
|
||||
@@ -470,6 +470,7 @@ nsPopupSetFrame::ActivatePopup(nsPopupFrameList* aEntry, PRBool aActivateFlag)
|
||||
// is set by setting the |menuactive| attribute. This used to trip css into showing the menu
|
||||
// but now we do it ourselves.
|
||||
if (aActivateFlag)
|
||||
// XXXben hook in |width| and |height| usage here?
|
||||
aEntry->mPopupContent->SetAttr(kNameSpaceID_None, nsXULAtoms::menutobedisplayed, NS_LITERAL_STRING("true"), PR_TRUE);
|
||||
else {
|
||||
aEntry->mPopupContent->UnsetAttr(kNameSpaceID_None, nsXULAtoms::menuactive, PR_TRUE);
|
||||
@@ -665,7 +666,7 @@ nsPopupSetFrame::OnDestroyed(nsIContent* aPopupContent)
|
||||
void
|
||||
nsPopupSetFrame::UpdateDismissalListener(nsIMenuParent* aMenuParent)
|
||||
{
|
||||
if (!nsMenuFrame::mDismissalListener) {
|
||||
if (!nsMenuFrame::sDismissalListener) {
|
||||
if (!aMenuParent)
|
||||
return;
|
||||
// Create the listener and attach it to the outermost window.
|
||||
@@ -674,7 +675,7 @@ nsPopupSetFrame::UpdateDismissalListener(nsIMenuParent* aMenuParent)
|
||||
|
||||
// Make sure the menu dismissal listener knows what the current
|
||||
// innermost menu popup frame is.
|
||||
nsMenuFrame::mDismissalListener->SetCurrentMenuParent(aMenuParent);
|
||||
nsMenuFrame::sDismissalListener->SetCurrentMenuParent(aMenuParent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
||||
Reference in New Issue
Block a user