|
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" |
|
14 |
|
15 class nsMenuBoxObject : public nsIMenuBoxObject, |
|
16 public nsBoxObject |
|
17 { |
|
18 public: |
|
19 NS_DECL_ISUPPORTS_INHERITED |
|
20 NS_DECL_NSIMENUBOXOBJECT |
|
21 |
|
22 nsMenuBoxObject(); |
|
23 virtual ~nsMenuBoxObject(); |
|
24 }; |
|
25 |
|
26 nsMenuBoxObject::nsMenuBoxObject() |
|
27 { |
|
28 } |
|
29 |
|
30 nsMenuBoxObject::~nsMenuBoxObject() |
|
31 { |
|
32 } |
|
33 |
|
34 NS_IMPL_ISUPPORTS_INHERITED(nsMenuBoxObject, nsBoxObject, nsIMenuBoxObject) |
|
35 |
|
36 /* void openMenu (in boolean openFlag); */ |
|
37 NS_IMETHODIMP nsMenuBoxObject::OpenMenu(bool aOpenFlag) |
|
38 { |
|
39 nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); |
|
40 if (pm) { |
|
41 nsIFrame* frame = GetFrame(false); |
|
42 if (frame) { |
|
43 if (aOpenFlag) { |
|
44 nsCOMPtr<nsIContent> content = mContent; |
|
45 pm->ShowMenu(content, false, false); |
|
46 } |
|
47 else { |
|
48 nsMenuFrame* menu = do_QueryFrame(frame); |
|
49 if (menu) { |
|
50 nsMenuPopupFrame* popupFrame = menu->GetPopup(); |
|
51 if (popupFrame) |
|
52 pm->HidePopup(popupFrame->GetContent(), false, true, false, false); |
|
53 } |
|
54 } |
|
55 } |
|
56 } |
|
57 |
|
58 return NS_OK; |
|
59 } |
|
60 |
|
61 NS_IMETHODIMP nsMenuBoxObject::GetActiveChild(nsIDOMElement** aResult) |
|
62 { |
|
63 *aResult = nullptr; |
|
64 nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); |
|
65 if (menu) |
|
66 return menu->GetActiveChild(aResult); |
|
67 return NS_OK; |
|
68 } |
|
69 |
|
70 NS_IMETHODIMP nsMenuBoxObject::SetActiveChild(nsIDOMElement* aResult) |
|
71 { |
|
72 nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); |
|
73 if (menu) |
|
74 return menu->SetActiveChild(aResult); |
|
75 return NS_OK; |
|
76 } |
|
77 |
|
78 /* boolean handleKeyPress (in nsIDOMKeyEvent keyEvent); */ |
|
79 NS_IMETHODIMP nsMenuBoxObject::HandleKeyPress(nsIDOMKeyEvent* aKeyEvent, bool* aHandledFlag) |
|
80 { |
|
81 *aHandledFlag = false; |
|
82 NS_ENSURE_ARG(aKeyEvent); |
|
83 |
|
84 nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); |
|
85 if (!pm) |
|
86 return NS_OK; |
|
87 |
|
88 // if event has already been handled, bail |
|
89 bool eventHandled = false; |
|
90 aKeyEvent->GetDefaultPrevented(&eventHandled); |
|
91 if (eventHandled) |
|
92 return NS_OK; |
|
93 |
|
94 if (nsMenuBarListener::IsAccessKeyPressed(aKeyEvent)) |
|
95 return NS_OK; |
|
96 |
|
97 nsMenuFrame* menu = do_QueryFrame(GetFrame(false)); |
|
98 if (!menu) |
|
99 return NS_OK; |
|
100 |
|
101 nsMenuPopupFrame* popupFrame = menu->GetPopup(); |
|
102 if (!popupFrame) |
|
103 return NS_OK; |
|
104 |
|
105 uint32_t keyCode; |
|
106 aKeyEvent->GetKeyCode(&keyCode); |
|
107 switch (keyCode) { |
|
108 case nsIDOMKeyEvent::DOM_VK_UP: |
|
109 case nsIDOMKeyEvent::DOM_VK_DOWN: |
|
110 case nsIDOMKeyEvent::DOM_VK_HOME: |
|
111 case nsIDOMKeyEvent::DOM_VK_END: |
|
112 { |
|
113 nsNavigationDirection theDirection; |
|
114 theDirection = NS_DIRECTION_FROM_KEY_CODE(popupFrame, keyCode); |
|
115 *aHandledFlag = |
|
116 pm->HandleKeyboardNavigationInPopup(popupFrame, theDirection); |
|
117 return NS_OK; |
|
118 } |
|
119 default: |
|
120 *aHandledFlag = pm->HandleShortcutNavigation(aKeyEvent, popupFrame); |
|
121 return NS_OK; |
|
122 } |
|
123 } |
|
124 |
|
125 NS_IMETHODIMP |
|
126 nsMenuBoxObject::GetOpenedWithKey(bool* aOpenedWithKey) |
|
127 { |
|
128 *aOpenedWithKey = false; |
|
129 |
|
130 nsMenuFrame* menuframe = do_QueryFrame(GetFrame(false)); |
|
131 if (!menuframe) |
|
132 return NS_OK; |
|
133 |
|
134 nsIFrame* frame = menuframe->GetParent(); |
|
135 while (frame) { |
|
136 nsMenuBarFrame* menubar = do_QueryFrame(frame); |
|
137 if (menubar) { |
|
138 *aOpenedWithKey = menubar->IsActiveByKeyboard(); |
|
139 return NS_OK; |
|
140 } |
|
141 frame = frame->GetParent(); |
|
142 } |
|
143 |
|
144 return NS_OK; |
|
145 } |
|
146 |
|
147 |
|
148 // Creation Routine /////////////////////////////////////////////////////////////////////// |
|
149 |
|
150 nsresult |
|
151 NS_NewMenuBoxObject(nsIBoxObject** aResult) |
|
152 { |
|
153 *aResult = new nsMenuBoxObject; |
|
154 if (!*aResult) |
|
155 return NS_ERROR_OUT_OF_MEMORY; |
|
156 NS_ADDREF(*aResult); |
|
157 return NS_OK; |
|
158 } |
|
159 |