Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: chrome/browser/chromeos/views/menu_locator.cc

Issue 6693032: Remove WebUI menu (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: " Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/views/menu_locator.h"
6
7 #include "base/i18n/rtl.h"
8 #include "base/logging.h"
9 #include "chrome/browser/chromeos/views/webui_menu_widget.h"
10 #include "ui/gfx/insets.h"
11 #include "ui/gfx/point.h"
12 #include "ui/gfx/rect.h"
13 #include "views/screen.h"
14 #include "views/widget/widget.h"
15
16 namespace {
17
18 using chromeos::WebUIMenuWidget;
19
20 // Menu's corner radious.
21 const int kMenuCornerRadius = 0; // crosbug.com/7718.
22 const int kSubmenuOverlapPx = 1;
23
24 gfx::Rect GetBoundsOf(const views::Widget* widget) {
25 return widget->GetClientAreaScreenBounds();
26 }
27
28 // Returns the Rect of the screen that contains the point (x, y).
29 gfx::Rect GetScreenRectAt(int x, int y) {
30 return views::Screen::GetMonitorAreaNearestPoint(gfx::Point(x, y));
31 }
32
33 // Returns adjusted height of the menu that fits to the screen's
34 // height, and enables scrolling if necessary.
35 int AdjustHeight(WebUIMenuWidget* widget,
36 int screen_height,
37 int height) {
38 // TODO(oshima): Locator needs a preferred size so that
39 // 1) we can tell height == screen_rect is the result of
40 // locator resizing it, or preferred size happens to be
41 // same hight of the screen (which is rare).
42 // 2) when the menu is moved to place where it has more space, it can
43 // hide the scrollbar again. (which won't happen on chromeos now)
44 if (height >= screen_height) {
45 widget->EnableScroll(true);
46 return screen_height;
47 }
48 widget->EnableScroll(false);
49 return height;
50 }
51
52 // Updates the root menu's bounds to fit to the screen.
53 void UpdateRootMenuBounds(WebUIMenuWidget* widget,
54 const gfx::Point& origin,
55 const gfx::Size& size,
56 bool align_right) {
57 gfx::Rect screen_rect = GetScreenRectAt(origin.x(), origin.y());
58 int width = std::min(screen_rect.width(), size.width());
59 int height = AdjustHeight(widget, screen_rect.height(), size.height());
60
61 int x = align_right ? origin.x() - width : origin.x();
62 int y = origin.y();
63 if (x + width > screen_rect.right())
64 x = screen_rect.right() - width;
65 if (y + height > screen_rect.bottom())
66 y = screen_rect.bottom() - height;
67 widget->SetBounds(gfx::Rect(x, y, width, height));
68 }
69
70 // MenuLocator for dropdown menu.
71 class DropDownMenuLocator : public chromeos::MenuLocator {
72 public:
73 explicit DropDownMenuLocator(const gfx::Point& origin)
74 : origin_(origin) {
75 }
76
77 private:
78 virtual SubmenuDirection GetSubmenuDirection() const {
79 return DEFAULT;
80 }
81
82 virtual void Move(WebUIMenuWidget* widget) {
83 // TODO(oshima):
84 // Dropdown Menu has to be shown above the button, which is not currently
85 // possible with Menu2. I'll update Menu2 and this code
86 // after beta.
87 gfx::Rect bounds = widget->GetClientAreaScreenBounds();
88 UpdateRootMenuBounds(widget, origin_, bounds.size(), !base::i18n::IsRTL());
89 }
90
91 virtual void SetBounds(WebUIMenuWidget* widget, const gfx::Size& size) {
92 gfx::Size new_size(size);
93 new_size.Enlarge(0, kMenuCornerRadius);
94 UpdateRootMenuBounds(widget, origin_, size, !base::i18n::IsRTL());
95 }
96
97 virtual void GetInsets(gfx::Insets* insets) const {
98 insets->Set(0, 0, kMenuCornerRadius, 0);
99 }
100
101 virtual const SkScalar* GetCorners() const {
102 static const SkScalar corners[] = {
103 0, 0,
104 0, 0,
105 kMenuCornerRadius, kMenuCornerRadius,
106 kMenuCornerRadius, kMenuCornerRadius,
107 };
108 return corners;
109 }
110
111 gfx::Point origin_;
112
113 DISALLOW_COPY_AND_ASSIGN(DropDownMenuLocator);
114 };
115
116 // MenuLocator for context menu.
117 class ContextMenuLocator : public chromeos::MenuLocator {
118 public:
119 explicit ContextMenuLocator(const gfx::Point& origin)
120 : origin_(origin) {
121 }
122
123 private:
124 virtual SubmenuDirection GetSubmenuDirection() const {
125 return DEFAULT;
126 }
127
128 virtual void Move(WebUIMenuWidget* widget) {
129 gfx::Rect bounds = widget->GetClientAreaScreenBounds();
130 UpdateRootMenuBounds(widget, origin_, bounds.size(), base::i18n::IsRTL());
131 }
132
133 virtual void SetBounds(WebUIMenuWidget* widget, const gfx::Size& size) {
134 gfx::Size new_size(size);
135 new_size.Enlarge(0, kMenuCornerRadius * 2);
136 UpdateRootMenuBounds(widget, origin_, new_size, base::i18n::IsRTL());
137 }
138
139 virtual const SkScalar* GetCorners() const {
140 static const SkScalar corners[] = {
141 kMenuCornerRadius, kMenuCornerRadius,
142 kMenuCornerRadius, kMenuCornerRadius,
143 kMenuCornerRadius, kMenuCornerRadius,
144 kMenuCornerRadius, kMenuCornerRadius,
145 };
146 return corners;
147 }
148
149 virtual void GetInsets(gfx::Insets* insets) const {
150 insets->Set(kMenuCornerRadius, 0, kMenuCornerRadius, 0);
151 }
152
153 gfx::Point origin_;
154
155 DISALLOW_COPY_AND_ASSIGN(ContextMenuLocator);
156 };
157
158 // MenuLocator for submenu.
159 class SubMenuLocator : public chromeos::MenuLocator {
160 public:
161 SubMenuLocator(const WebUIMenuWidget* parent,
162 MenuLocator::SubmenuDirection parent_direction,
163 int y)
164 : parent_rect_(GetBoundsOf(parent)),
165 parent_direction_(parent_direction),
166 root_y_(parent_rect_.y() + y),
167 corners_(NULL),
168 direction_(DEFAULT) {
169 }
170
171 private:
172 virtual SubmenuDirection GetSubmenuDirection() const {
173 return direction_;
174 }
175
176 virtual void Move(WebUIMenuWidget* widget) {
177 gfx::Rect bounds = widget->GetClientAreaScreenBounds();
178 UpdateBounds(widget, bounds.size());
179 }
180
181 virtual void SetBounds(WebUIMenuWidget* widget, const gfx::Size& size) {
182 gfx::Size new_size(size);
183 new_size.Enlarge(0, kMenuCornerRadius * 2);
184 UpdateBounds(widget, new_size);
185 }
186
187 virtual const SkScalar* GetCorners() const {
188 return corners_;
189 }
190
191 virtual void GetInsets(gfx::Insets* insets) const {
192 insets->Set(kMenuCornerRadius, 0, kMenuCornerRadius, 0);
193 }
194
195 // Rounded corner definitions for right/left attached submenu.
196 static const SkScalar kRightCorners[];
197 static const SkScalar kLeftCorners[];
198
199 void UpdateBounds(WebUIMenuWidget* widget, const gfx::Size& size) {
200 gfx::Rect screen_rect = GetScreenRectAt(parent_rect_.x(), root_y_);
201 int width = std::min(screen_rect.width(), size.width());
202 int height = AdjustHeight(widget, size.height(), screen_rect.height());
203
204 SubmenuDirection direction = parent_direction_;
205 if (direction == DEFAULT) {
206 if (base::i18n::IsRTL()) {
207 direction = LEFT;
208 } else {
209 direction = RIGHT;
210 }
211 }
212 // Adjust Y to fit the screen.
213 int y = root_y_;
214 if (root_y_ + height > screen_rect.bottom())
215 y = screen_rect.bottom() - height;
216 // Determine the attachment.
217 // TODO(oshima):
218 // Come up with better placement when menu is wide,
219 // probably limit max width and let each menu scroll
220 // horizontally when selected.
221 int x = direction == RIGHT ?
222 ComputeXToRight(screen_rect, width) :
223 ComputeXToLeft(screen_rect, width);
224 corners_ = direction_ == RIGHT ? kRightCorners : kLeftCorners;
225 widget->SetBounds(gfx::Rect(x, y, width, height));
226 }
227
228 int ComputeXToRight(const gfx::Rect& screen_rect, int width) {
229 if (parent_rect_.right() + width > screen_rect.right()) {
230 if (parent_rect_.x() - width < screen_rect.x()) {
231 // Place on the right to fit to the screen if no space on left
232 direction_ = RIGHT;
233 return screen_rect.right() - width;
234 }
235 direction_ = LEFT;
236 return parent_rect_.x() - width + kSubmenuOverlapPx;
237 } else {
238 direction_ = RIGHT;
239 return parent_rect_.right() - kSubmenuOverlapPx;
240 }
241 }
242
243 int ComputeXToLeft(const gfx::Rect& screen_rect, int width) {
244 if (parent_rect_.x() - width < screen_rect.x()) {
245 if (parent_rect_.right() + width > screen_rect.right()) {
246 // no space on right
247 direction_ = LEFT;
248 return screen_rect.x();
249 }
250 corners_ = kRightCorners;
251 direction_ = RIGHT;
252 return parent_rect_.right() - kSubmenuOverlapPx;
253 } else {
254 corners_ = kLeftCorners;
255 direction_ = LEFT;
256 return parent_rect_.x() - width + kSubmenuOverlapPx;
257 }
258 }
259
260 const gfx::Rect parent_rect_;
261
262 const MenuLocator::SubmenuDirection parent_direction_;
263
264 const int root_y_;
265
266 SkScalar const* corners_;
267
268 // The direction the this menu is attached to its parent. Submenu may still
269 // choose different direction if there is no spece for that direction
270 // (2nd turnaround).
271 SubmenuDirection direction_;
272
273 DISALLOW_COPY_AND_ASSIGN(SubMenuLocator);
274 };
275
276 // Rounded corners of the submenu attached to right side.
277 const SkScalar SubMenuLocator::kRightCorners[] = {
278 0, 0,
279 kMenuCornerRadius, kMenuCornerRadius,
280 kMenuCornerRadius, kMenuCornerRadius,
281 kMenuCornerRadius, kMenuCornerRadius,
282 };
283
284 // Rounded corners of the submenu attached to left side.
285 const SkScalar SubMenuLocator::kLeftCorners[] = {
286 kMenuCornerRadius, kMenuCornerRadius,
287 0, 0,
288 kMenuCornerRadius, kMenuCornerRadius,
289 kMenuCornerRadius, kMenuCornerRadius,
290 };
291
292
293 } // namespace
294
295 namespace chromeos {
296
297 // static
298 MenuLocator* MenuLocator::CreateDropDownMenuLocator(const gfx::Point& p) {
299 return new DropDownMenuLocator(p);
300 }
301
302 MenuLocator* MenuLocator::CreateContextMenuLocator(const gfx::Point& p) {
303 return new ContextMenuLocator(p);
304 }
305
306 MenuLocator* MenuLocator::CreateSubMenuLocator(
307 const WebUIMenuWidget* parent,
308 MenuLocator::SubmenuDirection parent_direction,
309 int y) {
310 return new SubMenuLocator(parent, parent_direction, y);
311 }
312
313 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/views/menu_locator.h ('k') | chrome/browser/chromeos/views/native_menu_webui.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698