The menu bar now supports shortcuts (e.g., ALT+f). Also repaired a minor problem

with keyboard navigation and mouse movement interoperability on the menus.
This commit is contained in:
hyatt%netscape.com 1999-07-23 07:39:16 +00:00
Родитель 199fafc79f
Коммит 7a62bb78f1
6 изменённых файлов: 81 добавлений и 23 удалений

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

@ -75,6 +75,7 @@ XUL_ATOM(xpmenuitem, "xpmenuitem") // Represents an XP menu item
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(shortcut, "shortcut") // The shortcut key for a menu or menu item
XUL_ATOM(progressmeter, "progressmeter")
XUL_ATOM(titledbutton, "titledbutton")

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

@ -155,10 +155,61 @@ nsMenuBarFrame::ToggleMenuActiveState()
}
}
nsIFrame*
nsMenuBarFrame::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.
nsCOMPtr<nsIAtom> tag;
current->GetTag(*getter_AddRefs(tag));
if (tag.get() == nsXULAtoms::xpmenu ||
tag.get() == nsXULAtoms::xpmenuitem) {
// Get the shortcut attribute.
nsString shortcutKey = "";
current->GetAttribute(kNameSpaceID_None, nsXULAtoms::shortcut, shortcutKey);
shortcutKey.ToUpperCase();
if (shortcutKey.Length() > 0) {
// We've got something.
PRUnichar shortcutChar = shortcutKey.CharAt(0);
if (shortcutChar == aLetter) {
// We match!
return currFrame;
}
}
}
currFrame->GetNextSibling(&currFrame);
}
return nsnull;
}
void
nsMenuBarFrame::ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag)
{
if (mCurrentMenu) {
nsMenuFrame* menuFrame = (nsMenuFrame*)mCurrentMenu;
if (menuFrame->IsOpen()) {
// No way this applies to us. Give it to our child.
menuFrame->ShortcutNavigation(aLetter, aHandledFlag);
return;
}
}
// This applies to us. Let's see if one of the shortcuts applies
nsIFrame* 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();
}
}
void

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

@ -59,6 +59,7 @@ public:
void ToggleMenuActiveState();
void KeyboardNavigation(PRUint32 aDirection);
void ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag);
nsIFrame* FindMenuWithShortcut(PRUint32 aLetter);
protected:
nsMenuBarListener* mMenuBarListener; // The listener that tells us about key and mouse events.

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

@ -248,7 +248,27 @@ nsMenuBarListener::KeyDown(nsIDOMEvent* aKeyEvent)
if (active)
mMenuBarFrame->KeyboardNavigation(theChar);
}
else {
// Get the character code.
nsCOMPtr<nsIDOMUIEvent> uiEvent = do_QueryInterface(aKeyEvent);
if (uiEvent) {
// See if a letter was pressed.
PRUint32 charCode;
uiEvent->GetKeyCode(&charCode);
if ((active || mAltKeyDown) &&
((charCode >= 'a' && charCode <= 'z') ||
(charCode >= 'A' && charCode <= 'Z')))
{
// Do shortcut navigation.
mAltKeyDown = PR_FALSE; // Clear this. ALT presses are irrelevant now.
// A letter was pressed. We want to see if a shortcut gets matched. If
// so, we'll know the menu got activated.
mMenuBarFrame->ShortcutNavigation(charCode, active);
}
}
}
if (active)
return NS_ERROR_BASE; // I am consuming event
return NS_OK; // means I am NOT consuming event
@ -262,26 +282,6 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent)
PRBool active = mMenuBarFrame->IsActive();
// Get the character code.
nsCOMPtr<nsIDOMUIEvent> uiEvent = do_QueryInterface(aKeyEvent);
if (uiEvent) {
// See if a letter was pressed.
PRUint32 charCode;
uiEvent->GetCharCode(&charCode);
if ((active || mAltKeyDown) &&
((charCode >= 'a' && charCode <= 'z') ||
(charCode >= 'A' && charCode <= 'Z')))
{
// Do shortcut navigation.
mAltKeyDown = PR_FALSE; // Clear this. ALT presses are irrelevant now.
// A letter was pressed. We want to see if a shortcut gets matched. If
// so, we'll know the menu got activated.
mMenuBarFrame->ShortcutNavigation(charCode, active);
}
}
if (active)
return NS_ERROR_BASE; // I am consuming event
return NS_OK; // means I am NOT consuming event

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

@ -201,7 +201,7 @@ nsMenuFrame::HandleEvent(nsIPresContext& aPresContext,
if (mMenuParent && !mMenuOpen)
mMenuParent->SetCurrentMenuItem(nsnull);
}
else if (aEvent->message == NS_MOUSE_ENTER) {
else if (aEvent->message == NS_MOUSE_MOVE) {
// Let the menu parent know we're the new item.
if (mMenuParent)
mMenuParent->SetCurrentMenuItem(this);
@ -330,7 +330,11 @@ nsMenuFrame::Reflow(nsIPresContext& aPresContext,
void
nsMenuFrame::ShortcutNavigation(PRUint32 aLetter, PRBool& aHandledFlag)
{
nsIFrame* frame = mPopupFrames.FirstChild();
if (frame) {
nsMenuPopupFrame* popup = (nsMenuPopupFrame*)frame;
popup->ShortcutNavigation(aLetter, aHandledFlag);
}
}
void

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

@ -75,6 +75,7 @@ XUL_ATOM(xpmenuitem, "xpmenuitem") // Represents an XP menu item
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(shortcut, "shortcut") // The shortcut key for a menu or menu item
XUL_ATOM(progressmeter, "progressmeter")
XUL_ATOM(titledbutton, "titledbutton")