Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / layout / xul / nsMenuBoxObject.cpp
blob6516f4fe01b36522fce029626cd90219f15dc9ef
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "nsISupportsUtils.h"
6 #include "nsIMenuBoxObject.h"
7 #include "nsBoxObject.h"
8 #include "nsIDOMKeyEvent.h"
9 #include "nsIFrame.h"
10 #include "nsMenuBarFrame.h"
11 #include "nsMenuBarListener.h"
12 #include "nsMenuFrame.h"
13 #include "nsMenuPopupFrame.h"
15 class nsMenuBoxObject : public nsIMenuBoxObject,
16 public nsBoxObject
18 public:
19 NS_DECL_ISUPPORTS_INHERITED
20 NS_DECL_NSIMENUBOXOBJECT
22 nsMenuBoxObject();
23 protected:
24 virtual ~nsMenuBoxObject();
27 nsMenuBoxObject::nsMenuBoxObject()
31 nsMenuBoxObject::~nsMenuBoxObject()
35 NS_IMPL_ISUPPORTS_INHERITED(nsMenuBoxObject, nsBoxObject, nsIMenuBoxObject)
37 /* void openMenu (in boolean openFlag); */
38 NS_IMETHODIMP nsMenuBoxObject::OpenMenu(bool aOpenFlag)
40 nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
41 if (pm) {
42 nsIFrame* frame = GetFrame(false);
43 if (frame) {
44 if (aOpenFlag) {
45 nsCOMPtr<nsIContent> content = mContent;
46 pm->ShowMenu(content, false, false);
48 else {
49 nsMenuFrame* menu = do_QueryFrame(frame);
50 if (menu) {
51 nsMenuPopupFrame* popupFrame = menu->GetPopup();
52 if (popupFrame)
53 pm->HidePopup(popupFrame->GetContent(), false, true, false, false);
59 return NS_OK;
62 NS_IMETHODIMP nsMenuBoxObject::GetActiveChild(nsIDOMElement** aResult)
64 *aResult = nullptr;
65 nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
66 if (menu)
67 return menu->GetActiveChild(aResult);
68 return NS_OK;
71 NS_IMETHODIMP nsMenuBoxObject::SetActiveChild(nsIDOMElement* aResult)
73 nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
74 if (menu)
75 return menu->SetActiveChild(aResult);
76 return NS_OK;
79 /* boolean handleKeyPress (in nsIDOMKeyEvent keyEvent); */
80 NS_IMETHODIMP nsMenuBoxObject::HandleKeyPress(nsIDOMKeyEvent* aKeyEvent, bool* aHandledFlag)
82 *aHandledFlag = false;
83 NS_ENSURE_ARG(aKeyEvent);
85 nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
86 if (!pm)
87 return NS_OK;
89 // if event has already been handled, bail
90 bool eventHandled = false;
91 aKeyEvent->GetDefaultPrevented(&eventHandled);
92 if (eventHandled)
93 return NS_OK;
95 if (nsMenuBarListener::IsAccessKeyPressed(aKeyEvent))
96 return NS_OK;
98 nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
99 if (!menu)
100 return NS_OK;
102 nsMenuPopupFrame* popupFrame = menu->GetPopup();
103 if (!popupFrame)
104 return NS_OK;
106 uint32_t keyCode;
107 aKeyEvent->GetKeyCode(&keyCode);
108 switch (keyCode) {
109 case nsIDOMKeyEvent::DOM_VK_UP:
110 case nsIDOMKeyEvent::DOM_VK_DOWN:
111 case nsIDOMKeyEvent::DOM_VK_HOME:
112 case nsIDOMKeyEvent::DOM_VK_END:
114 nsNavigationDirection theDirection;
115 theDirection = NS_DIRECTION_FROM_KEY_CODE(popupFrame, keyCode);
116 *aHandledFlag =
117 pm->HandleKeyboardNavigationInPopup(popupFrame, theDirection);
118 return NS_OK;
120 default:
121 *aHandledFlag = pm->HandleShortcutNavigation(aKeyEvent, popupFrame);
122 return NS_OK;
126 NS_IMETHODIMP
127 nsMenuBoxObject::GetOpenedWithKey(bool* aOpenedWithKey)
129 *aOpenedWithKey = false;
131 nsMenuFrame* menuframe = do_QueryFrame(GetFrame(false));
132 if (!menuframe)
133 return NS_OK;
135 nsIFrame* frame = menuframe->GetParent();
136 while (frame) {
137 nsMenuBarFrame* menubar = do_QueryFrame(frame);
138 if (menubar) {
139 *aOpenedWithKey = menubar->IsActiveByKeyboard();
140 return NS_OK;
142 frame = frame->GetParent();
145 return NS_OK;
149 // Creation Routine ///////////////////////////////////////////////////////////////////////
151 nsresult
152 NS_NewMenuBoxObject(nsIBoxObject** aResult)
154 *aResult = new nsMenuBoxObject;
155 if (!*aResult)
156 return NS_ERROR_OUT_OF_MEMORY;
157 NS_ADDREF(*aResult);
158 return NS_OK;