From 00b9c6f64c9a0f8eda651b07ff26a0a6015d3be1 Mon Sep 17 00:00:00 2001 From: "hyatt%netscape.com" Date: Sun, 25 Jul 1999 01:14:43 +0000 Subject: [PATCH] Cascading menus now work! --- layout/xul/base/src/nsMenuFrame.cpp | 35 +++++++++++++++++++++--- layout/xul/base/src/nsMenuFrame.h | 8 ++++-- layout/xul/base/src/nsMenuPopupFrame.cpp | 6 ++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/layout/xul/base/src/nsMenuFrame.cpp b/layout/xul/base/src/nsMenuFrame.cpp index 55180904d245..c6c9d2cffc11 100644 --- a/layout/xul/base/src/nsMenuFrame.cpp +++ b/layout/xul/base/src/nsMenuFrame.cpp @@ -71,6 +71,11 @@ NS_IMETHODIMP nsMenuFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) return NS_ERROR_NULL_POINTER; } *aInstancePtr = NULL; + if (aIID.Equals(nsITimerCallback::GetIID())) { + *aInstancePtr = (void*)(nsITimerCallback*) this; + NS_ADDREF_THIS(); + return NS_OK; + } return nsBoxFrame::QueryInterface(aIID, aInstancePtr); } @@ -232,13 +237,20 @@ nsMenuFrame::HandleEvent(nsIPresContext& aPresContext, } } } - else if (aEvent->message == NS_MOUSE_MOVE) { + else if (aEvent->message == NS_MOUSE_MOVE && mMenuParent) { // Let the menu parent know we're the new item. - if (mMenuParent) - mMenuParent->SetCurrentMenuItem(this); + mMenuParent->SetCurrentMenuItem(this); + + PRBool isMenuBar = PR_TRUE; + mMenuParent->IsMenuBar(isMenuBar); // If we're a menu (and not a menu item), // kick off the timer. + if (!isMenuBar && IsMenu() && !mMenuOpen && !mOpenTimer) { + // We're a menu, we're closed, and no timer has been kicked off. + NS_NewTimer(getter_AddRefs(mOpenTimer)); + mOpenTimer->Init(this, 250); // 250 ms delay + } } return NS_OK; } @@ -441,4 +453,19 @@ nsMenuFrame::IsMenu() if (tag.get() == nsXULAtoms::xpmenu) return PR_TRUE; return PR_FALSE; -} \ No newline at end of file +} + +void +nsMenuFrame::Notify(nsITimer* aTimer) +{ + // Our timer has fired. + if (!mMenuOpen && mMenuParent) { + nsAutoString active = ""; + mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, active); + if (active == "true") { + // We're still the active menu. + OpenMenu(PR_TRUE); + } + } + mOpenTimer = nsnull; +} diff --git a/layout/xul/base/src/nsMenuFrame.h b/layout/xul/base/src/nsMenuFrame.h index eac874abc26a..f0d9c8fa4d4f 100644 --- a/layout/xul/base/src/nsMenuFrame.h +++ b/layout/xul/base/src/nsMenuFrame.h @@ -31,19 +31,23 @@ #include "nsFrameList.h" #include "nsIMenuParent.h" #include "nsITimer.h" +#include "nsITimerCallback.h" nsresult NS_NewMenuFrame(nsIFrame** aResult, PRUint32 aFlags) ; class nsMenuBarFrame; class nsMenuPopupFrame; -class nsMenuFrame : public nsBoxFrame +class nsMenuFrame : public nsBoxFrame, public nsITimerCallback { public: nsMenuFrame(); NS_DECL_ISUPPORTS + // The nsITimerCallback interface + virtual void Notify(nsITimer *timer); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIContent* aContent, nsIFrame* aParent, @@ -95,7 +99,7 @@ public: void SetIsMenu(PRBool aIsMenu) { mIsMenu = aIsMenu; }; void GetMenuParent(nsIMenuParent** aResult) { NS_IF_ADDREF(mMenuParent); *aResult = mMenuParent; }; - + protected: void GetMenuChildrenElement(nsIContent** aResult); diff --git a/layout/xul/base/src/nsMenuPopupFrame.cpp b/layout/xul/base/src/nsMenuPopupFrame.cpp index 99dc9b4c7a18..9e34cbfb457a 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -501,6 +501,12 @@ nsMenuPopupFrame::KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag) aHandledFlag = PR_TRUE; } + else if (aDirection == NS_VK_LEFT && mCurrentMenu && + menuFrame->IsMenu()) { + // Close it up. + aHandledFlag = PR_TRUE; + menuFrame->OpenMenu(PR_FALSE); + } } NS_IMETHODIMP