michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: #include "nsISupportsUtils.h" michael@0: #include "nsIMenuBoxObject.h" michael@0: #include "nsBoxObject.h" michael@0: #include "nsIDOMKeyEvent.h" michael@0: #include "nsIFrame.h" michael@0: #include "nsMenuBarFrame.h" michael@0: #include "nsMenuBarListener.h" michael@0: #include "nsMenuFrame.h" michael@0: #include "nsMenuPopupFrame.h" michael@0: michael@0: class nsMenuBoxObject : public nsIMenuBoxObject, michael@0: public nsBoxObject michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS_INHERITED michael@0: NS_DECL_NSIMENUBOXOBJECT michael@0: michael@0: nsMenuBoxObject(); michael@0: virtual ~nsMenuBoxObject(); michael@0: }; michael@0: michael@0: nsMenuBoxObject::nsMenuBoxObject() michael@0: { michael@0: } michael@0: michael@0: nsMenuBoxObject::~nsMenuBoxObject() michael@0: { michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS_INHERITED(nsMenuBoxObject, nsBoxObject, nsIMenuBoxObject) michael@0: michael@0: /* void openMenu (in boolean openFlag); */ michael@0: NS_IMETHODIMP nsMenuBoxObject::OpenMenu(bool aOpenFlag) michael@0: { michael@0: nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); michael@0: if (pm) { michael@0: nsIFrame* frame = GetFrame(false); michael@0: if (frame) { michael@0: if (aOpenFlag) { michael@0: nsCOMPtr content = mContent; michael@0: pm->ShowMenu(content, false, false); michael@0: } michael@0: else { michael@0: nsMenuFrame* menu = do_QueryFrame(frame); michael@0: if (menu) { michael@0: nsMenuPopupFrame* popupFrame = menu->GetPopup(); michael@0: if (popupFrame) michael@0: pm->HidePopup(popupFrame->GetContent(), false, true, false, false); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsMenuBoxObject::GetActiveChild(nsIDOMElement** aResult) michael@0: { michael@0: *aResult = nullptr; michael@0: nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); michael@0: if (menu) michael@0: return menu->GetActiveChild(aResult); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsMenuBoxObject::SetActiveChild(nsIDOMElement* aResult) michael@0: { michael@0: nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); michael@0: if (menu) michael@0: return menu->SetActiveChild(aResult); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* boolean handleKeyPress (in nsIDOMKeyEvent keyEvent); */ michael@0: NS_IMETHODIMP nsMenuBoxObject::HandleKeyPress(nsIDOMKeyEvent* aKeyEvent, bool* aHandledFlag) michael@0: { michael@0: *aHandledFlag = false; michael@0: NS_ENSURE_ARG(aKeyEvent); michael@0: michael@0: nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); michael@0: if (!pm) michael@0: return NS_OK; michael@0: michael@0: // if event has already been handled, bail michael@0: bool eventHandled = false; michael@0: aKeyEvent->GetDefaultPrevented(&eventHandled); michael@0: if (eventHandled) michael@0: return NS_OK; michael@0: michael@0: if (nsMenuBarListener::IsAccessKeyPressed(aKeyEvent)) michael@0: return NS_OK; michael@0: michael@0: nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); michael@0: if (!menu) michael@0: return NS_OK; michael@0: michael@0: nsMenuPopupFrame* popupFrame = menu->GetPopup(); michael@0: if (!popupFrame) michael@0: return NS_OK; michael@0: michael@0: uint32_t keyCode; michael@0: aKeyEvent->GetKeyCode(&keyCode); michael@0: switch (keyCode) { michael@0: case nsIDOMKeyEvent::DOM_VK_UP: michael@0: case nsIDOMKeyEvent::DOM_VK_DOWN: michael@0: case nsIDOMKeyEvent::DOM_VK_HOME: michael@0: case nsIDOMKeyEvent::DOM_VK_END: michael@0: { michael@0: nsNavigationDirection theDirection; michael@0: theDirection = NS_DIRECTION_FROM_KEY_CODE(popupFrame, keyCode); michael@0: *aHandledFlag = michael@0: pm->HandleKeyboardNavigationInPopup(popupFrame, theDirection); michael@0: return NS_OK; michael@0: } michael@0: default: michael@0: *aHandledFlag = pm->HandleShortcutNavigation(aKeyEvent, popupFrame); michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsMenuBoxObject::GetOpenedWithKey(bool* aOpenedWithKey) michael@0: { michael@0: *aOpenedWithKey = false; michael@0: michael@0: nsMenuFrame* menuframe = do_QueryFrame(GetFrame(false)); michael@0: if (!menuframe) michael@0: return NS_OK; michael@0: michael@0: nsIFrame* frame = menuframe->GetParent(); michael@0: while (frame) { michael@0: nsMenuBarFrame* menubar = do_QueryFrame(frame); michael@0: if (menubar) { michael@0: *aOpenedWithKey = menubar->IsActiveByKeyboard(); michael@0: return NS_OK; michael@0: } michael@0: frame = frame->GetParent(); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: // Creation Routine /////////////////////////////////////////////////////////////////////// michael@0: michael@0: nsresult michael@0: NS_NewMenuBoxObject(nsIBoxObject** aResult) michael@0: { michael@0: *aResult = new nsMenuBoxObject; michael@0: if (!*aResult) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: NS_ADDREF(*aResult); michael@0: return NS_OK; michael@0: } michael@0: