Chrome event stuff. Menu changes.

This commit is contained in:
hyatt%netscape.com 1999-09-21 01:03:00 +00:00
Родитель dca1ddfd11
Коммит a8749017eb
16 изменённых файлов: 429 добавлений и 316 удалений

Просмотреть файл

@ -817,18 +817,24 @@ nsHTMLFrameInnerFrame::CreateWebShell(nsIPresContext& aPresContext,
mWebShell->SetWebShellType(parentType);
}
// Make sure all shells have links back to the nearest enclosing chrome
// shell.
// Make sure all shells have links back to the content element in the
// nearest enclosing chrome shell.
nsCOMPtr<nsIWebShell> chromeShell;
nsCOMPtr<nsIContent> chromeElement;
nsWebShellType chromeShellType;
outerShell->GetWebShellType(chromeShellType);
if (chromeShellType == nsWebShellChrome)
chromeShell = dont_QueryInterface(outerShell);
else
outerShell->GetContainingChromeShell(getter_AddRefs(chromeShell));
if (chromeShellType == nsWebShellChrome) {
// Our parent shell is a chrome shell. It is therefore our nearest
// enclosing chrome shell.
chromeElement = dont_QueryInterface(mContent);
}
else {
// Our parent shell is a content shell. Get the chrome info from
// it and use that for our shell as well.
outerShell->GetContainingChromeElement(getter_AddRefs(chromeElement));
}
mWebShell->SetContainingChromeShell(chromeShell);
mWebShell->SetContainingChromeElement(chromeElement);
#endif // INCLUDE_XUL

Просмотреть файл

@ -817,18 +817,24 @@ nsHTMLFrameInnerFrame::CreateWebShell(nsIPresContext& aPresContext,
mWebShell->SetWebShellType(parentType);
}
// Make sure all shells have links back to the nearest enclosing chrome
// shell.
// Make sure all shells have links back to the content element in the
// nearest enclosing chrome shell.
nsCOMPtr<nsIWebShell> chromeShell;
nsCOMPtr<nsIContent> chromeElement;
nsWebShellType chromeShellType;
outerShell->GetWebShellType(chromeShellType);
if (chromeShellType == nsWebShellChrome)
chromeShell = dont_QueryInterface(outerShell);
else
outerShell->GetContainingChromeShell(getter_AddRefs(chromeShell));
if (chromeShellType == nsWebShellChrome) {
// Our parent shell is a chrome shell. It is therefore our nearest
// enclosing chrome shell.
chromeElement = dont_QueryInterface(mContent);
}
else {
// Our parent shell is a content shell. Get the chrome info from
// it and use that for our shell as well.
outerShell->GetContainingChromeElement(getter_AddRefs(chromeElement));
}
mWebShell->SetContainingChromeShell(chromeShell);
mWebShell->SetContainingChromeElement(chromeElement);
#endif // INCLUDE_XUL

Просмотреть файл

@ -25,15 +25,16 @@
#define NS_IMENUPARENT_IID \
{ 0xd407bf61, 0x3efa, 0x11d3, { 0x97, 0xfa, 0x0, 0x40, 0x5, 0x53, 0xee, 0xf0 } }
class nsIMenuFrame;
class nsIMenuParent : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IMENUPARENT_IID; return iid; }
NS_IMETHOD SetCurrentMenuItem(nsIFrame* aMenuItem) = 0;
NS_IMETHOD GetNextMenuItem(nsIFrame* aStart, nsIFrame** aResult) = 0;
NS_IMETHOD GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult) = 0;
NS_IMETHOD SetCurrentMenuItem(nsIMenuFrame* aMenuItem) = 0;
NS_IMETHOD GetNextMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult) = 0;
NS_IMETHOD GetPreviousMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult) = 0;
NS_IMETHOD SetActive(PRBool aActiveFlag) = 0;
NS_IMETHOD GetIsActive(PRBool& isActive) = 0;
@ -42,6 +43,8 @@ public:
NS_IMETHOD DismissChain() = 0;
NS_IMETHOD HideChain() = 0;
NS_IMETHOD CreateDismissalListener() = 0;
};
#endif

Просмотреть файл

@ -38,6 +38,9 @@ public:
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment) = 0;
NS_IMETHOD HidePopup() = 0;
NS_IMETHOD DestroyPopup() = 0;
};
#endif

Просмотреть файл

@ -56,7 +56,7 @@ CPPSRCS = \
nsMenuFrame.cpp \
nsMenuBarFrame.cpp \
nsMenuBarListener.cpp \
nsMenuPopupEntryListener.cpp \
nsMenuDismissalListener.cpp \
nsPopupSetFrame.cpp \
nsRepeatService.cpp \
$(NULL)

Просмотреть файл

@ -55,7 +55,7 @@ CPPSRCS= \
nsMenuFrame.cpp \
nsMenuBarFrame.cpp \
nsMenuBarListener.cpp \
nsMenuPopupEntryListener.cpp \
nsMenuDismissalListener.cpp \
nsPopupSetFrame.cpp \
$(NULL)
@ -91,7 +91,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsMenuFrame.obj \
.\$(OBJDIR)\nsMenuBarFrame.obj \
.\$(OBJDIR)\nsMenuBarListener.obj \
.\$(OBJDIR)\nsMenuPopupEntryListener.obj \
.\$(OBJDIR)\nsMenuDismissalListener.obj \
.\$(OBJDIR)\nsPopupSetFrame.obj \
$(NULL)

Просмотреть файл

@ -25,15 +25,16 @@
#define NS_IMENUPARENT_IID \
{ 0xd407bf61, 0x3efa, 0x11d3, { 0x97, 0xfa, 0x0, 0x40, 0x5, 0x53, 0xee, 0xf0 } }
class nsIMenuFrame;
class nsIMenuParent : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IMENUPARENT_IID; return iid; }
NS_IMETHOD SetCurrentMenuItem(nsIFrame* aMenuItem) = 0;
NS_IMETHOD GetNextMenuItem(nsIFrame* aStart, nsIFrame** aResult) = 0;
NS_IMETHOD GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult) = 0;
NS_IMETHOD SetCurrentMenuItem(nsIMenuFrame* aMenuItem) = 0;
NS_IMETHOD GetNextMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult) = 0;
NS_IMETHOD GetPreviousMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult) = 0;
NS_IMETHOD SetActive(PRBool aActiveFlag) = 0;
NS_IMETHOD GetIsActive(PRBool& isActive) = 0;
@ -42,6 +43,8 @@ public:
NS_IMETHOD DismissChain() = 0;
NS_IMETHOD HideChain() = 0;
NS_IMETHOD CreateDismissalListener() = 0;
};
#endif

Просмотреть файл

@ -34,6 +34,8 @@
#include "nsIView.h"
#include "nsIViewManager.h"
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
//
// NS_NewMenuBarFrame
//
@ -137,9 +139,8 @@ nsMenuBarFrame::ToggleMenuActiveState()
mIsActive = PR_FALSE;
if (mCurrentMenu) {
// Deactivate the menu.
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
menuFrame->OpenMenu(PR_FALSE);
menuFrame->SelectMenu(PR_FALSE);
mCurrentMenu->OpenMenu(PR_FALSE);
mCurrentMenu->SelectMenu(PR_FALSE);
mCurrentMenu = nsnull;
}
}
@ -150,11 +151,10 @@ nsMenuBarFrame::ToggleMenuActiveState()
// Set the active menu to be the top left item (e.g., the File menu).
// We use an attribute called "active" to track the current active menu.
nsCOMPtr<nsIContent> firstMenuItem;
nsIFrame* firstFrame;
nsIMenuFrame* firstFrame;
GetNextMenuItem(nsnull, &firstFrame);
if (firstFrame) {
nsMenuFrame* menuFrame = (nsMenuFrame*)firstFrame;
menuFrame->SelectMenu(PR_TRUE);
firstFrame->SelectMenu(PR_TRUE);
// Track this item for keyboard navigation.
mCurrentMenu = firstFrame;
@ -162,7 +162,7 @@ nsMenuBarFrame::ToggleMenuActiveState()
}
}
nsIFrame*
nsIMenuFrame*
nsMenuBarFrame::FindMenuWithShortcut(PRUint32 aLetter)
{
// Enumerate over our list of frames.
@ -182,7 +182,10 @@ nsMenuBarFrame::FindMenuWithShortcut(PRUint32 aLetter)
PRUnichar shortcutChar = shortcutKey.CharAt(0);
if (shortcutChar == aLetter) {
// We match!
return currFrame;
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
if (menuFrame)
return menuFrame.get();
return nsnull;
}
}
}
@ -195,24 +198,24 @@ void
nsMenuBarFrame::ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag)
{
if (mCurrentMenu) {
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
if (menuFrame->IsOpen()) {
PRBool isOpen = PR_FALSE;
mCurrentMenu->MenuIsOpen(isOpen);
if (isOpen) {
// No way this applies to us. Give it to our child.
menuFrame->ShortcutNavigation(aLetter, aHandledFlag);
mCurrentMenu->ShortcutNavigation(aLetter, aHandledFlag);
return;
}
}
// This applies to us. Let's see if one of the shortcuts applies
nsIFrame* result = FindMenuWithShortcut(aLetter);
nsIMenuFrame* result = FindMenuWithShortcut(aLetter);
if (result) {
// We got one!
aHandledFlag = PR_TRUE;
mIsActive = PR_TRUE;
nsMenuFrame* menuFrame = (nsMenuFrame*)result;
SetCurrentMenuItem(result);
menuFrame->OpenMenu(PR_TRUE);
menuFrame->SelectFirstItem();
result->OpenMenu(PR_TRUE);
result->SelectFirstItem();
}
}
@ -221,13 +224,17 @@ nsMenuBarFrame::KeyboardNavigation(PRUint32 aDirection)
{
if (!mCurrentMenu)
return;
PRBool isContainer = PR_FALSE;
PRBool isOpen = PR_FALSE;
mCurrentMenu->MenuIsContainer(isContainer);
mCurrentMenu->MenuIsOpen(isOpen);
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
PRBool handled = PR_FALSE;
if (menuFrame->IsOpen()) {
if (isOpen) {
// Let the child menu try to handle it.
menuFrame->KeyboardNavigation(aDirection, handled);
mCurrentMenu->KeyboardNavigation(aDirection, handled);
}
if (handled)
@ -235,7 +242,7 @@ nsMenuBarFrame::KeyboardNavigation(PRUint32 aDirection)
if (aDirection == NS_VK_RIGHT || aDirection == NS_VK_LEFT) {
nsIFrame* nextItem;
nsIMenuFrame* nextItem;
if (aDirection == NS_VK_RIGHT)
GetNextMenuItem(mCurrentMenu, &nextItem);
@ -243,28 +250,32 @@ nsMenuBarFrame::KeyboardNavigation(PRUint32 aDirection)
SetCurrentMenuItem(nextItem);
if (nextItem) {
nsMenuFrame* menu = (nsMenuFrame*)nextItem;
if (menu->IsOpen()) {
PRBool nextIsOpen;
nextItem->MenuIsOpen(nextIsOpen);
if (nextIsOpen) {
// Select the first item.
menu->SelectFirstItem();
nextItem->SelectFirstItem();
}
}
}
else if (aDirection == NS_VK_UP || aDirection == NS_VK_DOWN) {
// Open the menu and select its first item.
menuFrame->OpenMenu(PR_TRUE);
menuFrame->SelectFirstItem();
mCurrentMenu->OpenMenu(PR_TRUE);
mCurrentMenu->SelectFirstItem();
}
}
NS_IMETHODIMP
nsMenuBarFrame::GetNextMenuItem(nsIFrame* aStart, nsIFrame** aResult)
nsMenuBarFrame::GetNextMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult)
{
nsIFrame* currFrame;
nsIFrame* currFrame = nsnull;
nsIFrame* startFrame = nsnull;
if (aStart) {
currFrame = aStart;
if (currFrame)
aStart->QueryInterface(kIFrameIID, (void**)&currFrame);
if (currFrame) {
startFrame = currFrame;
currFrame->GetNextSibling(&currFrame);
}
}
else currFrame = mFrames.FirstChild();
@ -274,7 +285,9 @@ nsMenuBarFrame::GetNextMenuItem(nsIFrame* aStart, nsIFrame** aResult)
// See if it's a menu item.
if (IsValidItem(current)) {
*aResult = currFrame;
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
*aResult = menuFrame.get();
NS_IF_ADDREF(*aResult);
return NS_OK;
}
currFrame->GetNextSibling(&currFrame);
@ -283,13 +296,15 @@ nsMenuBarFrame::GetNextMenuItem(nsIFrame* aStart, nsIFrame** aResult)
currFrame = mFrames.FirstChild();
// Still don't have anything. Try cycling from the beginning.
while (currFrame && currFrame != aStart) {
while (currFrame && currFrame != startFrame) {
nsCOMPtr<nsIContent> current;
currFrame->GetContent(getter_AddRefs(current));
// See if it's a menu item.
if (IsValidItem(current)) {
*aResult = currFrame;
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
*aResult = menuFrame.get();
NS_IF_ADDREF(*aResult);
return NS_OK;
}
@ -302,13 +317,16 @@ nsMenuBarFrame::GetNextMenuItem(nsIFrame* aStart, nsIFrame** aResult)
}
NS_IMETHODIMP
nsMenuBarFrame::GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult)
nsMenuBarFrame::GetPreviousMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult)
{
nsIFrame* currFrame;
nsIFrame* currFrame = nsnull;
nsIFrame* startFrame = nsnull;
if (aStart) {
currFrame = aStart;
if (currFrame)
aStart->QueryInterface(kIFrameIID, (void**)&currFrame);
if (currFrame) {
startFrame = currFrame;
currFrame = mFrames.GetPrevSiblingFor(currFrame);
}
}
else currFrame = mFrames.LastChild();
@ -318,7 +336,9 @@ nsMenuBarFrame::GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult)
// See if it's a menu item.
if (IsValidItem(current)) {
*aResult = currFrame;
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
*aResult = menuFrame.get();
NS_IF_ADDREF(*aResult);
return NS_OK;
}
currFrame = mFrames.GetPrevSiblingFor(currFrame);
@ -327,13 +347,15 @@ nsMenuBarFrame::GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult)
currFrame = mFrames.LastChild();
// Still don't have anything. Try cycling from the end.
while (currFrame && currFrame != aStart) {
while (currFrame && currFrame != startFrame) {
nsCOMPtr<nsIContent> current;
currFrame->GetContent(getter_AddRefs(current));
// See if it's a menu item.
if (IsValidItem(current)) {
*aResult = currFrame;
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
*aResult = menuFrame.get();
NS_IF_ADDREF(*aResult);
return NS_OK;
}
@ -345,31 +367,28 @@ nsMenuBarFrame::GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult)
return NS_OK;
}
NS_IMETHODIMP nsMenuBarFrame::SetCurrentMenuItem(nsIFrame* aMenuItem)
NS_IMETHODIMP nsMenuBarFrame::SetCurrentMenuItem(nsIMenuFrame* aMenuItem)
{
if (mCurrentMenu == aMenuItem)
return NS_OK;
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
PRBool wasOpen = PR_FALSE;
// Unset the current child.
if (mCurrentMenu) {
wasOpen = menuFrame->IsOpen();
mCurrentMenu->MenuIsOpen(wasOpen);
if (wasOpen)
menuFrame->OpenMenu(PR_FALSE);
menuFrame->SelectMenu(PR_FALSE);
mCurrentMenu->OpenMenu(PR_FALSE);
mCurrentMenu->SelectMenu(PR_FALSE);
}
// Set the new child.
if (aMenuItem) {
nsMenuFrame* newFrame = (nsMenuFrame*)aMenuItem;
newFrame->SelectMenu(PR_TRUE);
newFrame->MarkAsGenerated(); // Have the menu building. Get it ready to be shown.
aMenuItem->SelectMenu(PR_TRUE);
aMenuItem->MarkAsGenerated(); // Have the menu building. Get it ready to be shown.
if (wasOpen)
newFrame->OpenMenu(PR_TRUE);
aMenuItem->OpenMenu(PR_TRUE);
}
mCurrentMenu = aMenuItem;
@ -384,15 +403,16 @@ nsMenuBarFrame::Escape()
return;
// See if our menu is open.
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
if (menuFrame->IsOpen()) {
PRBool isOpen = PR_FALSE;
mCurrentMenu->MenuIsOpen(isOpen);
if (isOpen) {
// Let the child menu handle this.
PRBool handled = PR_FALSE;
menuFrame->Escape(handled);
mCurrentMenu->Escape(handled);
if (!handled) {
// Close up this menu but keep our current menu item
// designation.
menuFrame->OpenMenu(PR_FALSE);
mCurrentMenu->OpenMenu(PR_FALSE);
}
return;
}
@ -411,25 +431,25 @@ nsMenuBarFrame::Enter()
return;
// See if our menu is open.
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
if (menuFrame->IsOpen()) {
PRBool isOpen = PR_FALSE;
mCurrentMenu->MenuIsOpen(isOpen);
if (isOpen) {
// Let the child menu handle this.
menuFrame->Enter();
mCurrentMenu->Enter();
return;
}
// It's us. Open the current menu.
menuFrame->OpenMenu(PR_TRUE);
menuFrame->SelectFirstItem();
mCurrentMenu->OpenMenu(PR_TRUE);
mCurrentMenu->SelectFirstItem();
}
NS_IMETHODIMP
nsMenuBarFrame::HideChain()
{
if (mCurrentMenu) {
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
menuFrame->ActivateMenu(PR_FALSE);
menuFrame->SelectMenu(PR_FALSE);
mCurrentMenu->ActivateMenu(PR_FALSE);
mCurrentMenu->SelectMenu(PR_FALSE);
}
return NS_OK;
}
@ -442,6 +462,31 @@ nsMenuBarFrame::DismissChain()
return NS_OK;
}
NS_IMETHODIMP
nsMenuBarFrame::CreateDismissalListener()
{
// Create the listener.
nsMenuFrame::mMenuDismissalListener = new nsMenuDismissalListener();
// Get the global object for the content node and convert it to a DOM
// window.
nsCOMPtr<nsIDocument> doc;
mContent->GetDocument(*getter_AddRefs(doc));
if (!doc)
return NS_OK;
doc->GetScriptContextOwner(...);
owner->GetScriptGlobalObject(...);
// qi global object to an nsidomwindow
// Walk up the parent chain until we reach the outermost window.
// Attach ourselves as a mousedown listener.
return NS_OK;
}
PRBool
nsMenuBarFrame::IsValidItem(nsIContent* aContent)
@ -478,4 +523,3 @@ nsMenuBarFrame::Destroy(nsIPresContext& aPresContext)
return nsToolbarFrame::Destroy(aPresContext);
}

Просмотреть файл

@ -31,6 +31,7 @@
#include "nsIMenuParent.h"
class nsIContent;
class nsIMenuFrame;
nsresult NS_NewMenuBarFrame(nsIFrame** aResult) ;
@ -43,9 +44,9 @@ public:
NS_DECL_ISUPPORTS
// nsIMenuParentInterface
NS_IMETHOD SetCurrentMenuItem(nsIFrame* aMenuItem);
NS_IMETHOD GetNextMenuItem(nsIFrame* aStart, nsIFrame** aResult);
NS_IMETHOD GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult);
NS_IMETHOD SetCurrentMenuItem(nsIMenuFrame* aMenuItem);
NS_IMETHOD GetNextMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult);
NS_IMETHOD GetPreviousMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult);
NS_IMETHOD SetActive(PRBool aActiveFlag);
NS_IMETHOD GetIsActive(PRBool& isActive) { isActive = IsActive(); return NS_OK; };
NS_IMETHOD IsMenuBar(PRBool& isMenuBar) { isMenuBar = PR_TRUE; return NS_OK; };
@ -58,6 +59,9 @@ public:
// Hides the chain of cascaded menus without closing them up.
NS_IMETHOD HideChain();
// The dismissal listener gets created and attached to the window.
NS_IMETHOD CreateDismissalListener();
NS_IMETHOD Init(nsIPresContext& aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
@ -76,7 +80,7 @@ public:
// Used to handle ALT+key combos
void ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag);
nsIFrame* FindMenuWithShortcut(PRUint32 aLetter);
nsIMenuFrame* FindMenuWithShortcut(PRUint32 aLetter);
// Called when the ESC key is held down to close levels of menus.
void Escape();
@ -90,7 +94,7 @@ public:
protected:
nsMenuBarListener* mMenuBarListener; // The listener that tells us about key and mouse events.
PRBool mIsActive; // Whether or not the menu bar is active (a menu item is highlighted or shown).
nsIFrame* mCurrentMenu; // The current menu that is active.
nsIMenuFrame* mCurrentMenu; // The current menu that is active.
nsIDOMEventReceiver* mTarget;

Просмотреть файл

@ -45,6 +45,8 @@
static PRInt32 gEatMouseMove = PR_FALSE;
nsMenuDismissalListener* nsMenuFrame::mDismissalListener = nsnull;
//
// NS_NewMenuFrame
//
@ -84,7 +86,12 @@ NS_IMETHODIMP nsMenuFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(nsIAnonymousContentCreator::GetIID())) {
if (aIID.Equals(nsIMenuFrame::GetIID())) {
*aInstancePtr = (void*)(nsIMenuFrame*)this;
NS_ADDREF_THIS();
return NS_OK;
}
else if (aIID.Equals(nsIAnonymousContentCreator::GetIID())) {
*aInstancePtr = (void*)(nsIAnonymousContentCreator*) this;
NS_ADDREF_THIS();
return NS_OK;
@ -287,7 +294,7 @@ nsMenuFrame::HandleEvent(nsIPresContext& aPresContext,
return NS_OK;
}
void
NS_IMETHODIMP
nsMenuFrame::ToggleMenuState()
{
if (mMenuOpen) {
@ -296,9 +303,11 @@ nsMenuFrame::ToggleMenuState()
else {
OpenMenu(PR_TRUE);
}
return NS_OK;
}
void
NS_IMETHODIMP
nsMenuFrame::SelectMenu(PRBool aActivateFlag)
{
if (aActivateFlag) {
@ -309,6 +318,8 @@ nsMenuFrame::SelectMenu(PRBool aActivateFlag)
// Unhighlight the menu.
mContent->UnsetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, PR_TRUE);
}
return NS_OK;
}
PRBool nsMenuFrame::IsGenerated()
@ -329,7 +340,8 @@ PRBool nsMenuFrame::IsGenerated()
return PR_TRUE;
}
void nsMenuFrame::MarkAsGenerated()
NS_IMETHODIMP
nsMenuFrame::MarkAsGenerated()
{
nsCOMPtr<nsIContent> child;
GetMenuChildrenElement(getter_AddRefs(child));
@ -343,9 +355,11 @@ void nsMenuFrame::MarkAsGenerated()
if (genVal == "")
child->SetAttribute(kNameSpaceID_None, nsXULAtoms::menugenerated, "true", PR_TRUE);
}
return NS_OK;
}
void
NS_IMETHODIMP
nsMenuFrame::ActivateMenu(PRBool aActivateFlag)
{
// Activate the menu without opening it.
@ -358,6 +372,8 @@ nsMenuFrame::ActivateMenu(PRBool aActivateFlag)
child->SetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, "true", PR_TRUE);
else child->UnsetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, PR_TRUE);
}
return NS_OK;
}
NS_IMETHODIMP
@ -392,7 +408,7 @@ nsMenuFrame::AttributeChanged(nsIPresContext* aPresContext,
return NS_OK;
}
void
NS_IMETHODIMP
nsMenuFrame::OpenMenu(PRBool aActivateFlag)
{
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(mContent);
@ -404,6 +420,8 @@ nsMenuFrame::OpenMenu(PRBool aActivateFlag)
domElement->SetAttribute("open", "true");
}
else domElement->RemoveAttribute("open");
return NS_OK;
}
void
@ -425,6 +443,9 @@ nsMenuFrame::OpenMenuInternal(PRBool aActivateFlag)
nsIFrame* frame = mPopupFrames.FirstChild();
nsMenuPopupFrame* menuPopup = (nsMenuPopupFrame*)frame;
nsCOMPtr<nsIMenuParent> childPopup = do_QueryInterface(frame);
UpdateDismissalListener(childPopup);
ActivateMenu(PR_TRUE);
if (menuPopup) {
// Tell the menu bar we're active.
@ -447,6 +468,8 @@ nsMenuFrame::OpenMenuInternal(PRBool aActivateFlag)
if (!OnDestroy())
return;
UpdateDismissalListener(mMenuParent);
nsIFrame* frame = mPopupFrames.FirstChild();
nsMenuPopupFrame* menuPopup = (nsMenuPopupFrame*)frame;
@ -586,7 +609,7 @@ nsMenuFrame::Dirty(const nsHTMLReflowState& aReflowState, nsIFrame*& incremental
return rv;
}
void
NS_IMETHODIMP
nsMenuFrame::ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag)
{
nsIFrame* frame = mPopupFrames.FirstChild();
@ -594,9 +617,11 @@ nsMenuFrame::ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag)
nsMenuPopupFrame* popup = (nsMenuPopupFrame*)frame;
popup->ShortcutNavigation(aLetter, aHandledFlag);
}
return NS_OK;
}
void
NS_IMETHODIMP
nsMenuFrame::KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag)
{
nsIFrame* frame = mPopupFrames.FirstChild();
@ -604,9 +629,11 @@ nsMenuFrame::KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag)
nsMenuPopupFrame* popup = (nsMenuPopupFrame*)frame;
popup->KeyboardNavigation(aDirection, aHandledFlag);
}
return NS_OK;
}
void
NS_IMETHODIMP
nsMenuFrame::Escape(PRBool& aHandledFlag)
{
nsIFrame* frame = mPopupFrames.FirstChild();
@ -614,9 +641,11 @@ nsMenuFrame::Escape(PRBool& aHandledFlag)
nsMenuPopupFrame* popup = (nsMenuPopupFrame*)frame;
popup->Escape(aHandledFlag);
}
return NS_OK;
}
void
NS_IMETHODIMP
nsMenuFrame::Enter()
{
if (!mMenuOpen) {
@ -630,7 +659,7 @@ nsMenuFrame::Enter()
SelectFirstItem();
}
return;
return NS_OK;
}
nsIFrame* frame = mPopupFrames.FirstChild();
@ -638,18 +667,22 @@ nsMenuFrame::Enter()
nsMenuPopupFrame* popup = (nsMenuPopupFrame*)frame;
popup->Enter();
}
return NS_OK;
}
void
NS_IMETHODIMP
nsMenuFrame::SelectFirstItem()
{
nsIFrame* frame = mPopupFrames.FirstChild();
if (frame) {
nsMenuPopupFrame* popup = (nsMenuPopupFrame*)frame;
nsIFrame* result;
nsIMenuFrame* result;
popup->GetNextMenuItem(nsnull, &result);
popup->SetCurrentMenuItem(result);
}
return NS_OK;
}
PRBool
@ -744,6 +777,11 @@ nsMenuFrame::CreateAnonymousContent(nsISupportsArray& aAnonymousChildren)
onMenuBar ? "menubar-left" : "menu-left" , PR_FALSE);
aAnonymousChildren.AppendElement(content);
nsAutoString beforeString;
nsAutoString accessString;
nsAutoString afterString;
SplitOnShortcut(beforeString, accessString, afterString);
/*
* Create the .menu-text titledbutton, and propagate crop, accesskey and
* value attributes. If we're a menubar, make the class menubar-text
@ -802,27 +840,6 @@ nsMenuFrame::CreateAnonymousContent(nsISupportsArray& aAnonymousChildren)
aAnonymousChildren.AppendElement(content);
}
// Make this insertion explicit.
/*PRUint32 count = 0;
aAnonymousChildren.Count(&count);
PRUint32 i;
for (i=0; i < count; i++)
{
// get our child's content and set its parent to our content
nsCOMPtr<nsISupports> node;
aAnonymousChildren.GetElementAt(i,getter_AddRefs(node));
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
mContent->AppendChildTo(content, PR_TRUE);
}
// Empty the array.
for (i=0; i < count; i++)
{
aAnonymousChildren.RemoveElementAt(0);
}
*/
return NS_OK;
}
@ -1080,3 +1097,16 @@ nsMenuFrame::AppendFrames(nsIPresContext& aPresContext,
return rv;
}
void
nsMenuFrame::UpdateDismissalListener(nsIMenuParent* aMenuParent)
{
if (!nsMenuFrame::mDismissalListener) {
// Create the listener and attach it to the outermost window.
aMenuParent->CreateDismissalListener();
}
// Make sure the menu dismissal listener knows what the current
// innermost menu popup frame is.
nsMenuFrame::mDismissalListener->SetCurrentMenuParent(aMenuParent);
}

Просмотреть файл

@ -31,6 +31,8 @@
#include "nsBoxFrame.h"
#include "nsFrameList.h"
#include "nsIMenuParent.h"
#include "nsIMenuFrame.h"
#include "nsMenuDismissalListener.h"
#include "nsITimer.h"
#include "nsITimerCallback.h"
#include "nsISupportsArray.h"
@ -42,7 +44,10 @@ nsresult NS_NewMenuFrame(nsIFrame** aResult, PRUint32 aFlags) ;
class nsMenuBarFrame;
class nsMenuPopupFrame;
class nsMenuFrame : public nsBoxFrame, public nsITimerCallback, public nsIAnonymousContentCreator
class nsMenuFrame : public nsBoxFrame,
public nsIMenuFrame,
public nsITimerCallback,
public nsIAnonymousContentCreator
{
public:
nsMenuFrame();
@ -109,33 +114,39 @@ public:
nsIAtom* aListName,
nsIFrame* aOldFrame);
void KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag);
void ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag);
void Escape(PRBool& aHandledFlag);
void Enter();
// nsIMenuFrame Interface
NS_IMETHOD KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag);
NS_IMETHOD ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag);
NS_IMETHOD Escape(PRBool& aHandledFlag);
NS_IMETHOD Enter();
void ToggleMenuState();
void SelectMenu(PRBool aActivateFlag);
NS_IMETHOD ToggleMenuState();
NS_IMETHOD SelectMenu(PRBool aActivateFlag);
void OpenMenu(PRBool aActivateFlag);
NS_IMETHOD OpenMenu(PRBool aActivateFlag);
void ActivateMenu(PRBool aActivateFlag);
NS_IMETHOD ActivateMenu(PRBool aActivateFlag);
NS_IMETHOD MenuIsContainer(PRBool& aResult) { aResult = IsMenu(); return NS_OK; };
PRBool IsMenu();
void SelectFirstItem();
NS_IMETHOD SelectFirstItem();
NS_IMETHOD MenuIsOpen(PRBool& aResult) { aResult = IsOpen(); return NS_OK; };
PRBool IsOpen() { return mMenuOpen; };
void SetIsMenu(PRBool aIsMenu) { mIsMenu = aIsMenu; };
void GetMenuParent(nsIMenuParent** aResult) { NS_IF_ADDREF(mMenuParent); *aResult = mMenuParent; };
NS_IMETHOD GetMenuParent(nsIMenuParent** aResult) { NS_IF_ADDREF(mMenuParent); *aResult = mMenuParent; return NS_OK; };
PRBool IsDisabled();
void MarkAsGenerated();
NS_IMETHOD MarkAsGenerated();
PRBool IsGenerated();
void SetIsMenu(PRBool aIsMenu) { mIsMenu = aIsMenu; };
protected:
static void UpdateDismissalListener(nsIMenuParent* aMenuParent);
void OpenMenuInternal(PRBool aActivateFlag);
void GetMenuChildrenElement(nsIContent** aResult);
@ -169,6 +180,8 @@ protected:
nsIMenuParent* mMenuParent; // Our parent menu.
nsCOMPtr<nsITimer> mOpenTimer;
nsIPresContext* mPresContext; // Our pres context.
static nsMenuDismissalListener* mDismissalListener; // The listener that dismisses menus.
}; // class nsMenuFrame
#endif

Просмотреть файл

@ -1,95 +0,0 @@
/* -*- 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 "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/
*
* 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.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsMenuPopupEntryListener.h"
#include "nsMenuPopupFrame.h"
#include "nsIDOMMouseMotionListener.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDOMEventListener.h"
// Drag & Drop, Clipboard
#include "nsIServiceManager.h"
#include "nsWidgetsCID.h"
#include "nsCOMPtr.h"
#include "nsIDOMUIEvent.h"
#include "nsIPresContext.h"
#include "nsIContent.h"
#include "nsIDOMNode.h"
#include "nsIDOMElement.h"
#include "nsXULAtoms.h"
#include "nsIEventStateManager.h"
#include "nsIViewManager.h"
#include "nsIView.h"
#include "nsISupportsArray.h"
/*
* nsMenuPopupEntryListener implementation
*/
NS_IMPL_ADDREF(nsMenuPopupEntryListener)
NS_IMPL_RELEASE(nsMenuPopupEntryListener)
////////////////////////////////////////////////////////////////////////
nsMenuPopupEntryListener::nsMenuPopupEntryListener(nsMenuPopupFrame* aMenuPopup)
{
NS_INIT_REFCNT();
mMenuPopupFrame = aMenuPopup;
}
////////////////////////////////////////////////////////////////////////
nsMenuPopupEntryListener::~nsMenuPopupEntryListener()
{
}
////////////////////////////////////////////////////////////////////////
nsresult
nsMenuPopupEntryListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(nsCOMTypeInfo<nsIDOMEventReceiver>::GetIID())) {
*aInstancePtr = (void*)(nsIDOMEventListener*)(nsIDOMKeyListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsCOMTypeInfo<nsIDOMMouseMotionListener>::GetIID())) {
*aInstancePtr = (void*)(nsIDOMMouseMotionListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMKeyListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
////////////////////////////////////////////////////////////////////////
nsresult
nsMenuPopupEntryListener::MouseMove(nsIDOMEvent* aMouseEvent)
{
//mMenuPopupFrame->CaptureMouseEvents(PR_TRUE);
return NS_OK;
}

Просмотреть файл

@ -30,12 +30,12 @@
#include "nsIViewManager.h"
#include "nsWidgetsCID.h"
#include "nsMenuFrame.h"
#include "nsMenuPopupEntryListener.h"
#include "nsIPopupSetFrame.h"
const PRInt32 kMaxZ = 0x7fffffff; //XXX: Shouldn't there be a define somewhere for MaxInt for PRInt32
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
//
// NS_NewMenuPopupFrame
//
// Wrapper for creating a new menu popup container
@ -88,7 +88,7 @@ NS_IMETHODIMP nsMenuPopupFrame::QueryInterface(REFNSIID aIID, void** aInstancePt
// nsMenuPopupFrame cntr
//
nsMenuPopupFrame::nsMenuPopupFrame()
:mCurrentMenu(nsnull), mMenuPopupEntryListener(nsnull)
:mCurrentMenu(nsnull)
{
} // cntr
@ -154,12 +154,14 @@ nsMenuPopupFrame::Init(nsIPresContext& aPresContext,
// the menu (have to use moves, since enter is completely flaky).
// Create the menu bar listener.
mMenuPopupEntryListener = new nsMenuPopupEntryListener(this);
/*mMenuPopupEntryListener = new nsMenuPopupEntryListener(this);
nsCOMPtr<nsIDOMEventReceiver> target = do_QueryInterface(mContent);
nsIDOMEventListener* domEventListener = (nsIDOMMouseMotionListener*)mMenuPopupEntryListener;
target->AddEventListener("mousemove", domEventListener, PR_FALSE);
return rv;
*/
return rv;
}
void
@ -247,23 +249,29 @@ nsMenuPopupFrame::DidReflow(nsIPresContext& aPresContext,
}
NS_IMETHODIMP
nsMenuPopupFrame::GetNextMenuItem(nsIFrame* aStart, nsIFrame** aResult)
nsMenuPopupFrame::GetNextMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult)
{
nsIFrame* currFrame;
nsIFrame* currFrame = nsnull;
nsIFrame* startFrame = nsnull;
if (aStart) {
currFrame = aStart;
if (currFrame)
aStart->QueryInterface(kIFrameIID, (void**)&currFrame);
if (currFrame) {
startFrame = currFrame;
currFrame->GetNextSibling(&currFrame);
}
}
else currFrame = mFrames.FirstChild();
nsIFrame* start = currFrame;
while (currFrame) {
nsCOMPtr<nsIContent> current;
currFrame->GetContent(getter_AddRefs(current));
// See if it's a menu item.
if (IsValidItem(current)) {
*aResult = currFrame;
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
*aResult = menuFrame.get();
NS_IF_ADDREF(*aResult);
return NS_OK;
}
currFrame->GetNextSibling(&currFrame);
@ -272,13 +280,15 @@ nsMenuPopupFrame::GetNextMenuItem(nsIFrame* aStart, nsIFrame** aResult)
currFrame = mFrames.FirstChild();
// Still don't have anything. Try cycling from the beginning.
while (currFrame && currFrame != aStart) {
while (currFrame && currFrame != startFrame) {
nsCOMPtr<nsIContent> current;
currFrame->GetContent(getter_AddRefs(current));
// See if it's a menu item.
if (IsValidItem(current)) {
*aResult = currFrame;
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
*aResult = menuFrame.get();
NS_IF_ADDREF(*aResult);
return NS_OK;
}
@ -291,13 +301,16 @@ nsMenuPopupFrame::GetNextMenuItem(nsIFrame* aStart, nsIFrame** aResult)
}
NS_IMETHODIMP
nsMenuPopupFrame::GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult)
nsMenuPopupFrame::GetPreviousMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult)
{
nsIFrame* currFrame;
nsIFrame* currFrame = nsnull;
nsIFrame* startFrame = nsnull;
if (aStart) {
currFrame = aStart;
if (currFrame)
aStart->QueryInterface(kIFrameIID, (void**)&currFrame);
if (currFrame) {
startFrame = currFrame;
currFrame = mFrames.GetPrevSiblingFor(currFrame);
}
}
else currFrame = mFrames.LastChild();
@ -307,7 +320,9 @@ nsMenuPopupFrame::GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult)
// See if it's a menu item.
if (IsValidItem(current)) {
*aResult = currFrame;
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
*aResult = menuFrame.get();
NS_IF_ADDREF(*aResult);
return NS_OK;
}
currFrame = mFrames.GetPrevSiblingFor(currFrame);
@ -316,13 +331,15 @@ nsMenuPopupFrame::GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult)
currFrame = mFrames.LastChild();
// Still don't have anything. Try cycling from the end.
while (currFrame && currFrame != aStart) {
while (currFrame && currFrame != startFrame) {
nsCOMPtr<nsIContent> current;
currFrame->GetContent(getter_AddRefs(current));
// See if it's a menu item.
if (IsValidItem(current)) {
*aResult = currFrame;
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
*aResult = menuFrame.get();
NS_IF_ADDREF(*aResult);
return NS_OK;
}
@ -334,24 +351,23 @@ nsMenuPopupFrame::GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult)
return NS_OK;
}
NS_IMETHODIMP nsMenuPopupFrame::SetCurrentMenuItem(nsIFrame* aMenuItem)
NS_IMETHODIMP nsMenuPopupFrame::SetCurrentMenuItem(nsIMenuFrame* aMenuItem)
{
if (mCurrentMenu == aMenuItem)
return NS_OK;
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
// Unset the current child.
if (mCurrentMenu) {
if (menuFrame->IsOpen())
menuFrame->OpenMenu(PR_FALSE);
menuFrame->SelectMenu(PR_FALSE);
PRBool isOpen = PR_FALSE;
mCurrentMenu->MenuIsOpen(isOpen);
if (isOpen)
mCurrentMenu->OpenMenu(PR_FALSE);
mCurrentMenu->SelectMenu(PR_FALSE);
}
// Set the new child.
if (aMenuItem) {
nsMenuFrame* newFrame = (nsMenuFrame*)aMenuItem;
newFrame->SelectMenu(PR_TRUE);
aMenuItem->SelectMenu(PR_TRUE);
}
mCurrentMenu = aMenuItem;
@ -377,11 +393,11 @@ nsMenuPopupFrame::CaptureMouseEvents(PRBool aGrabMouseEvents)
if (aGrabMouseEvents) {
viewMan->GrabMouseEvents(view,result);
mIsCapturingMouseEvents = PR_TRUE;
widget->CaptureMouse(PR_TRUE);
//widget->CaptureMouse(PR_TRUE);
} else {
viewMan->GrabMouseEvents(nsnull,result);
mIsCapturingMouseEvents = PR_FALSE;
widget->CaptureMouse(PR_FALSE);
//widget->CaptureMouse(PR_FALSE);
}
}
}
@ -396,13 +412,14 @@ nsMenuPopupFrame::Escape(PRBool& aHandledFlag)
return;
// See if our menu is open.
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
if (menuFrame->IsOpen()) {
PRBool isOpen = PR_FALSE;
mCurrentMenu->MenuIsOpen(isOpen);
if (isOpen) {
// Let the child menu handle this.
menuFrame->Escape(aHandledFlag);
mCurrentMenu->Escape(aHandledFlag);
if (!aHandledFlag) {
// We should close up.
menuFrame->OpenMenu(PR_FALSE);
mCurrentMenu->OpenMenu(PR_FALSE);
aHandledFlag = PR_TRUE;
}
return;
@ -412,15 +429,12 @@ nsMenuPopupFrame::Escape(PRBool& aHandledFlag)
void
nsMenuPopupFrame::Enter()
{
if (!mCurrentMenu)
return;
// Give it to the child.
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
menuFrame->Enter();
if (mCurrentMenu)
mCurrentMenu->Enter();
}
nsIFrame*
nsIMenuFrame*
nsMenuPopupFrame::FindMenuWithShortcut(PRUint32 aLetter)
{
// Enumerate over our list of frames.
@ -440,7 +454,10 @@ nsMenuPopupFrame::FindMenuWithShortcut(PRUint32 aLetter)
PRUnichar shortcutChar = shortcutKey.CharAt(0);
if (shortcutChar == aLetter) {
// We match!
return currFrame;
nsCOMPtr<nsIMenuFrame> menuFrame = do_QueryInterface(currFrame);
if (menuFrame)
return menuFrame.get();
return nsnull;
}
}
}
@ -453,25 +470,26 @@ void
nsMenuPopupFrame::ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag)
{
if (mCurrentMenu) {
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
if (menuFrame->IsOpen()) {
PRBool isOpen = PR_FALSE;
mCurrentMenu->MenuIsOpen(isOpen);
if (isOpen) {
// No way this applies to us. Give it to our child.
menuFrame->ShortcutNavigation(aLetter, aHandledFlag);
mCurrentMenu->ShortcutNavigation(aLetter, aHandledFlag);
return;
}
}
// This applies to us. Let's see if one of the shortcuts applies
nsIFrame* result = FindMenuWithShortcut(aLetter);
nsIMenuFrame* result = FindMenuWithShortcut(aLetter);
if (result) {
// We got one!
aHandledFlag = PR_TRUE;
nsMenuFrame* menuFrame = (nsMenuFrame*)result;
SetCurrentMenuItem(result);
menuFrame->OpenMenu(PR_TRUE);
menuFrame->SelectFirstItem();
result->OpenMenu(PR_TRUE);
result->SelectFirstItem();
// XXX For menu items, do an execution of the onclick handler!
// XXX For menu items, do an execution of the oncommand handler!
// Still needed or did I do this already? I'm going senile. - Dave
}
}
@ -479,13 +497,11 @@ void
nsMenuPopupFrame::KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag)
{
// This method only gets called if we're open.
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
if (!mCurrentMenu && (aDirection == NS_VK_RIGHT || aDirection == NS_VK_LEFT)) {
// We've been opened, but we haven't had anything selected.
// We can handle RIGHT, but our parent handles LEFT.
if (aDirection == NS_VK_RIGHT) {
nsIFrame* nextItem;
nsIMenuFrame* nextItem;
GetNextMenuItem(nsnull, &nextItem);
if (nextItem) {
aHandledFlag = PR_TRUE;
@ -495,16 +511,21 @@ nsMenuPopupFrame::KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag)
return;
}
if (menuFrame) {
if (menuFrame->IsOpen()) {
PRBool isContainer = PR_FALSE;
PRBool isOpen = PR_FALSE;
if (mCurrentMenu) {
mCurrentMenu->MenuIsContainer(isContainer);
mCurrentMenu->MenuIsOpen(isOpen);
if (isOpen) {
// Give our child a shot.
menuFrame->KeyboardNavigation(aDirection, aHandledFlag);
mCurrentMenu->KeyboardNavigation(aDirection, aHandledFlag);
}
else if (aDirection == NS_VK_RIGHT && menuFrame->IsMenu()) {
else if (aDirection == NS_VK_RIGHT && isContainer) {
// The menu is not yet open. Open it and select the first item.
aHandledFlag = PR_TRUE;
menuFrame->OpenMenu(PR_TRUE);
menuFrame->SelectFirstItem();
mCurrentMenu->OpenMenu(PR_TRUE);
mCurrentMenu->SelectFirstItem();
}
}
@ -514,7 +535,7 @@ nsMenuPopupFrame::KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag)
// For the vertical direction, we can move up or down.
if (aDirection == NS_VK_UP || aDirection == NS_VK_DOWN) {
nsIFrame* nextItem;
nsIMenuFrame* nextItem;
if (aDirection == NS_VK_DOWN)
GetNextMenuItem(mCurrentMenu, &nextItem);
@ -524,22 +545,52 @@ nsMenuPopupFrame::KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag)
aHandledFlag = PR_TRUE;
}
else if (mCurrentMenu && menuFrame->IsMenu() && menuFrame->IsOpen()) {
else if (mCurrentMenu && isContainer && isOpen) {
if (aDirection == NS_VK_LEFT) {
// Close it up.
menuFrame->OpenMenu(PR_FALSE);
mCurrentMenu->OpenMenu(PR_FALSE);
aHandledFlag = PR_TRUE;
}
}
}
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;
}
NS_IMETHODIMP
nsMenuPopupFrame::HideChain()
{
nsIFrame* frame;
GetParent(&frame);
if (frame) {
nsMenuFrame* menuFrame = (nsMenuFrame*)frame;
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;
menuFrame->ActivateMenu(PR_FALSE);
menuFrame->SelectMenu(PR_FALSE);
@ -560,7 +611,17 @@ nsMenuPopupFrame::DismissChain()
nsIFrame* frame;
GetParent(&frame);
if (frame) {
nsMenuFrame* menuFrame = (nsMenuFrame*)frame;
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;
menuFrame->OpenMenu(PR_FALSE);
// Get the parent.
@ -573,6 +634,12 @@ nsMenuPopupFrame::DismissChain()
return NS_OK;
}
NS_IMETHODIMP
nsMenuPopupFrame::CreateDismissalListener()
{
return NS_OK;
}
PRBool
nsMenuPopupFrame::IsValidItem(nsIContent* aContent)
{
@ -601,21 +668,26 @@ nsMenuPopupFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
aEventStatus = nsEventStatus_eConsumeDoDefault;
if (aEvent->message == NS_MOUSE_MOVE) {
#ifdef DEBUG_hyatt
printf("Mouse enter!\n");
#endif
//HandleMouseEnterEvent(aPresContext, aEvent, aEventStatus);
}
return NS_OK;
return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
NS_IMETHODIMP
nsMenuPopupFrame::Destroy(nsIPresContext& aPresContext)
{
nsCOMPtr<nsIDOMEventReceiver> target = do_QueryInterface(mContent);
target->RemoveEventListener("mousemove", mMenuPopupEntryListener, PR_TRUE);
//nsCOMPtr<nsIDOMEventReceiver> target = do_QueryInterface(mContent);
//target->RemoveEventListener("mousemove", mMenuPopupEntryListener, PR_TRUE);
return nsBoxFrame::Destroy(aPresContext);
}
NS_IMETHODIMP
nsMenuPopupFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
{
nsRect rect;
GetRect(rect);
if (rect.Contains(aPoint)) {
return nsBoxFrame::GetFrameForPoint(aPoint, aFrame);
}
*aFrame = this;
return NS_OK;
}

Просмотреть файл

@ -34,7 +34,8 @@ nsresult NS_NewMenuPopupFrame(nsIFrame** aResult) ;
class nsIViewManager;
class nsIView;
class nsMenuPopupEntryListener;
class nsIMenuParent;
class nsIMenuFrame;
class nsMenuPopupFrame : public nsBoxFrame, public nsIMenuParent
{
@ -44,19 +45,24 @@ public:
NS_DECL_ISUPPORTS
// nsIMenuParentInterface
NS_IMETHOD SetCurrentMenuItem(nsIFrame* aMenuItem);
NS_IMETHOD GetNextMenuItem(nsIFrame* aStart, nsIFrame** aResult);
NS_IMETHOD GetPreviousMenuItem(nsIFrame* aStart, nsIFrame** aResult);
NS_IMETHOD SetCurrentMenuItem(nsIMenuFrame* aMenuItem);
NS_IMETHOD GetNextMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult);
NS_IMETHOD GetPreviousMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult);
NS_IMETHOD SetActive(PRBool aActiveFlag) { return NS_OK; }; // We don't care.
NS_IMETHOD GetIsActive(PRBool& isActive) { isActive = PR_FALSE; return NS_OK; };
NS_IMETHOD IsMenuBar(PRBool& isMenuBar) { isMenuBar = PR_FALSE; return NS_OK; };
NS_IMETHOD GetParentPopup(nsIMenuParent** aResult);
// Closes up the chain of open cascaded menus.
NS_IMETHOD DismissChain();
// Hides the chain of cascaded menus without closing them up.
NS_IMETHOD HideChain();
// The dismissal listener gets created and attached to the window.
NS_IMETHOD CreateDismissalListener();
// Overridden methods
NS_IMETHOD Init(nsIPresContext& aPresContext,
nsIContent* aContent,
@ -73,6 +79,8 @@ public:
NS_IMETHOD Destroy(nsIPresContext& aPresContext);
NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame);
void GetViewOffset(nsIViewManager* aManager, nsIView* aView, nsPoint& aPoint);
void GetNearestEnclosingView(nsIFrame* aStartFrame, nsIView** aResult);
@ -84,7 +92,7 @@ public:
void KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag);
void ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag);
nsIFrame* FindMenuWithShortcut(PRUint32 aLetter);
nsIMenuFrame* FindMenuWithShortcut(PRUint32 aLetter);
void Escape(PRBool& aHandledFlag);
void Enter();
@ -93,9 +101,8 @@ public:
PRBool IsDisabled(nsIContent* aContent);
protected:
nsIFrame* mCurrentMenu; // The current menu that is active.
nsIMenuFrame* mCurrentMenu; // The current menu that is active.
PRBool mIsCapturingMouseEvents; // Whether or not we're grabbing the mouse events.
nsMenuPopupEntryListener* mMenuPopupEntryListener;
}; // class nsMenuPopupFrame
#endif

Просмотреть файл

@ -395,6 +395,20 @@ nsPopupSetFrame::CreatePopup(nsIFrame* aElementFrame, nsIContent* aPopupContent,
return NS_OK;
}
NS_IMETHODIMP
nsPopupSetFrame::HidePopup()
{
ActivatePopup(PR_FALSE);
return NS_OK;
}
NS_IMETHODIMP
nsPopupSetFrame::DestroyPopup()
{
OpenPopup(PR_FALSE);
return NS_OK;
}
void
nsPopupSetFrame::MarkAsGenerated(nsIContent* aPopupContent)
{

Просмотреть файл

@ -94,6 +94,9 @@ public:
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment);
NS_IMETHOD HidePopup();
NS_IMETHOD DestroyPopup();
PRBool OnCreate(nsIContent* aPopupContent);
PRBool OnDestroy();