Teaching the menu bar how to highlight the first item when the ALT key

is pressed.
This commit is contained in:
hyatt%netscape.com 1999-07-19 08:09:30 +00:00
parent a05d7023a3
commit b7a4382dfa
6 changed files with 85 additions and 9 deletions

View File

@ -71,6 +71,7 @@ XUL_ATOM(xpmenubar, "xpmenubar") // An XP menu bar.
XUL_ATOM(xpmenu, "xpmenu") // Represents an XP menu
XUL_ATOM(xpmenubutton, "xpmenubutton") // A titled button (with improved behavior) inside an XP menu.
XUL_ATOM(xpmenuchildren, "xpmenuchildren") // The XP menu's children.
XUL_ATOM(menuactive, "menuactive") // Whether or not a menu is active (without necessarily being open)
XUL_ATOM(progressmeter, "progressmeter")
XUL_ATOM(titledbutton, "titledbutton")

View File

@ -28,6 +28,7 @@
#include "nsINameSpaceManager.h"
#include "nsIDocument.h"
#include "nsIDOMEventReceiver.h"
#include "nsXULAtoms.h"
//
// NS_NewMenuBarFrame
@ -88,3 +89,45 @@ nsMenuBarFrame::Init(nsIPresContext& aPresContext,
return rv;
}
void
nsMenuBarFrame::ToggleMenuActiveState()
{
if (IsActive()) {
// Deactivate the menu bar
mIsActive = PR_FALSE;
if (mCurrentMenu) {
// Deactivate the menu.
mCurrentMenu->UnsetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, PR_TRUE);
mCurrentMenu = nsnull;
}
}
else {
// Activate the menu bar
mIsActive = PR_TRUE;
// 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;
GetFirstMenuItem(getter_AddRefs(firstMenuItem));
if (firstMenuItem) {
// Activate the item.
firstMenuItem->SetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, "true", PR_TRUE);
// Track this item for keyboard navigation.
mCurrentMenu = firstMenuItem.get();
}
}
}
void
nsMenuBarFrame::GetFirstMenuItem(nsIContent** aMenuItem)
{
PRInt32 childCount;
*aMenuItem = nsnull;
mContent->ChildCount(childCount);
if (childCount > 0) {
// We have at least one menu item. Good. Fetch it.
mContent->ChildAt(0, *aMenuItem);
}
}

View File

@ -26,11 +26,11 @@
#include "prtypes.h"
#include "nsIAtom.h"
#include "nsCOMPtr.h"
#include "nsToolbarFrame.h"
#include "nsMenuBarListener.h"
class nsIContent;
nsresult NS_NewMenuBarFrame(nsIFrame** aResult) ;
class nsMenuBarFrame : public nsToolbarFrame
@ -46,10 +46,13 @@ public:
// Non-interface helpers
PRBool IsActive() { return mIsActive; };
void ToggleMenuActiveState();
void GetFirstMenuItem(nsIContent** aResult);
protected:
nsMenuBarListener* mMenuBarListener;
PRBool mIsActive;
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).
nsIContent* mCurrentMenu; // The current menu that is active.
}; // class nsMenuBarFrame
#endif

View File

@ -50,6 +50,7 @@ NS_IMPL_RELEASE(nsMenuBarListener)
////////////////////////////////////////////////////////////////////////
nsMenuBarListener::nsMenuBarListener(nsMenuBarFrame* aMenuBar)
:mAltKeyDown(PR_FALSE)
{
NS_INIT_REFCNT();
mMenuBarFrame = aMenuBar;
@ -186,21 +187,47 @@ nsMenuBarListener::MouseOut(nsIDOMEvent* aMouseEvent)
////////////////////////////////////////////////////////////////////////
nsresult
nsMenuBarListener::KeyUp(nsIDOMEvent* aMouseEvent)
{
nsMenuBarListener::KeyUp(nsIDOMEvent* aKeyEvent)
{
// On a press of the ALT key by itself, we toggle the menu's
// active/inactive state.
// Get the ascii key code.
nsCOMPtr<nsIDOMUIEvent> theEvent = do_QueryInterface(aKeyEvent);
PRUint32 theChar;
theEvent->GetKeyCode(&theChar);
if (theChar == 18 && mAltKeyDown) {
// The ALT key was down and is now up.
mAltKeyDown = PR_FALSE;
mMenuBarFrame->ToggleMenuActiveState();
}
return NS_OK; // means I am NOT consuming event
}
////////////////////////////////////////////////////////////////////////
nsresult
nsMenuBarListener::KeyDown(nsIDOMEvent* aMouseEvent)
nsMenuBarListener::KeyDown(nsIDOMEvent* aKeyEvent)
{
nsCOMPtr<nsIDOMUIEvent> theEvent = do_QueryInterface(aKeyEvent);
PRUint32 theChar;
theEvent->GetKeyCode(&theChar);
if (theChar == 18) {
// The ALT key just went down. Track this.
mAltKeyDown = PR_TRUE;
}
return NS_OK; // means I am NOT consuming event
}
////////////////////////////////////////////////////////////////////////
nsresult
nsMenuBarListener::KeyPress(nsIDOMEvent* aMouseEvent)
nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent)
{
nsCOMPtr<nsIDOMUIEvent> theEvent = do_QueryInterface(aKeyEvent);
// On a press of the ALT key by itself, we toggle the menu's
// active/inactive state.
// Test Alt attribute
PRBool isAlt = PR_FALSE;
theEvent->GetAltKey(&isAlt);
return NS_OK; // means I am NOT consuming event
}

View File

@ -56,7 +56,8 @@ public:
NS_DECL_ISUPPORTS
protected:
nsMenuBarFrame* mMenuBarFrame;
nsMenuBarFrame* mMenuBarFrame; // The menu bar object.
PRBool mAltKeyDown; // Whether or not the ALT key is currently down.
};

View File

@ -71,6 +71,7 @@ XUL_ATOM(xpmenubar, "xpmenubar") // An XP menu bar.
XUL_ATOM(xpmenu, "xpmenu") // Represents an XP menu
XUL_ATOM(xpmenubutton, "xpmenubutton") // A titled button (with improved behavior) inside an XP menu.
XUL_ATOM(xpmenuchildren, "xpmenuchildren") // The XP menu's children.
XUL_ATOM(menuactive, "menuactive") // Whether or not a menu is active (without necessarily being open)
XUL_ATOM(progressmeter, "progressmeter")
XUL_ATOM(titledbutton, "titledbutton")