зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
199fafc79f
Коммит
7a62bb78f1
|
@ -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")
|
||||
|
|
Загрузка…
Ссылка в новой задаче