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

Side by Side Diff: chrome/views/chrome_menu.cc

Issue 7344: Convert GetPreferredSize from:... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years, 2 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
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/views/chrome_menu.h" 5 #include "chrome/views/chrome_menu.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <uxtheme.h> 8 #include <uxtheme.h>
9 #include <Vssym32.h> 9 #include <Vssym32.h>
10 10
11 #include "base/base_drag_source.h" 11 #include "base/base_drag_source.h"
12 #include "base/gfx/native_theme.h" 12 #include "base/gfx/native_theme.h"
13 #include "base/gfx/skia_utils.h" 13 #include "base/gfx/skia_utils.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/task.h" 15 #include "base/task.h"
16 #include "base/timer.h" 16 #include "base/timer.h"
17 #include "base/win_util.h" 17 #include "base/win_util.h"
18 #include "chrome/browser/drag_utils.h" 18 #include "chrome/browser/drag_utils.h"
19 #include "chrome/common/gfx/chrome_canvas.h" 19 #include "chrome/common/gfx/chrome_canvas.h"
20 #include "chrome/common/gfx/color_utils.h" 20 #include "chrome/common/gfx/color_utils.h"
21 #include "chrome/common/l10n_util.h" 21 #include "chrome/common/l10n_util.h"
22 #include "chrome/common/os_exchange_data.h" 22 #include "chrome/common/os_exchange_data.h"
23 #include "chrome/views/border.h" 23 #include "chrome/views/border.h"
24 #include "chrome/views/hwnd_view_container.h" 24 #include "chrome/views/hwnd_view_container.h"
25 #include "chrome/views/root_view.h" 25 #include "chrome/views/root_view.h"
26 #include "generated_resources.h" 26 #include "generated_resources.h"
27 27
28 #undef min
29 #undef max
30
28 // Margins between the top of the item and the label. 31 // Margins between the top of the item and the label.
29 static const int kItemTopMargin = 3; 32 static const int kItemTopMargin = 3;
30 33
31 // Margins between the bottom of the item and the label. 34 // Margins between the bottom of the item and the label.
32 static const int kItemBottomMargin = 4; 35 static const int kItemBottomMargin = 4;
33 36
34 // Margins between the left of the item and the icon. 37 // Margins between the left of the item and the icon.
35 static const int kItemLeftMargin = 4; 38 static const int kItemLeftMargin = 4;
36 39
37 // Padding between the label and submenu arrow. 40 // Padding between the label and submenu arrow.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 91
89 // Color of the drop indicator. 92 // Color of the drop indicator.
90 static const SkColor kDropIndicatorColor = SK_ColorBLACK; 93 static const SkColor kDropIndicatorColor = SK_ColorBLACK;
91 94
92 // Whether or not the gutter should be rendered. The gutter is specific to 95 // Whether or not the gutter should be rendered. The gutter is specific to
93 // Vista. 96 // Vista.
94 static bool render_gutter = false; 97 static bool render_gutter = false;
95 98
96 // Max width of a menu. There does not appear to be an OS value for this, yet 99 // Max width of a menu. There does not appear to be an OS value for this, yet
97 // both IE and FF restrict the max width of a menu. 100 // both IE and FF restrict the max width of a menu.
98 static const LONG kMaxMenuWidth = 400; 101 static const int kMaxMenuWidth = 400;
99 102
100 // Period of the scroll timer (in milliseconds). 103 // Period of the scroll timer (in milliseconds).
101 static const int kScrollTimerMS = 30; 104 static const int kScrollTimerMS = 30;
102 105
103 // Preferred height of menu items. Reset every time a menu is run. 106 // Preferred height of menu items. Reset every time a menu is run.
104 static int pref_menu_height; 107 static int pref_menu_height;
105 108
106 // Are mnemonics shown? This is updated before the menus are shown. 109 // Are mnemonics shown? This is updated before the menus are shown.
107 static bool show_mnemonics; 110 static bool show_mnemonics;
108 111
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 } 163 }
161 164
162 item_right_margin = kLabelToArrowPadding + arrow_width + kArrowToEdgePadding; 165 item_right_margin = kLabelToArrowPadding + arrow_width + kArrowToEdgePadding;
163 166
164 label_start = kItemLeftMargin + check_width + kIconToLabelPadding; 167 label_start = kItemLeftMargin + check_width + kIconToLabelPadding;
165 if (render_gutter) 168 if (render_gutter)
166 label_start += gutter_width + kGutterToLabel; 169 label_start += gutter_width + kGutterToLabel;
167 170
168 ReleaseDC(NULL, dc); 171 ReleaseDC(NULL, dc);
169 172
170 CSize pref;
171 MenuItemView menu_item(NULL); 173 MenuItemView menu_item(NULL);
172 menu_item.SetTitle(L"blah"); // Text doesn't matter here. 174 menu_item.SetTitle(L"blah"); // Text doesn't matter here.
173 menu_item.GetPreferredSize(&pref); 175 pref_menu_height = menu_item.GetPreferredSize().height();
174 pref_menu_height = pref.cy;
175 } 176 }
176 177
177 namespace { 178 namespace {
178 179
179 // Convenience for scrolling the view such that the origin is visible. 180 // Convenience for scrolling the view such that the origin is visible.
180 static void ScrollToVisible(View* view) { 181 static void ScrollToVisible(View* view) {
181 view->ScrollRectToVisible(0, 0, view->width(), view->height()); 182 view->ScrollRectToVisible(0, 0, view->width(), view->height());
182 } 183 }
183 184
184 // MenuScrollTask -------------------------------------------------------------- 185 // MenuScrollTask --------------------------------------------------------------
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 273
273 class MenuScrollButton : public View { 274 class MenuScrollButton : public View {
274 public: 275 public:
275 explicit MenuScrollButton(SubmenuView* host, bool is_up) 276 explicit MenuScrollButton(SubmenuView* host, bool is_up)
276 : host_(host), 277 : host_(host),
277 is_up_(is_up), 278 is_up_(is_up),
278 // Make our height the same as that of other MenuItemViews. 279 // Make our height the same as that of other MenuItemViews.
279 pref_height_(pref_menu_height) { 280 pref_height_(pref_menu_height) {
280 } 281 }
281 282
282 virtual void GetPreferredSize(CSize* out) { 283 virtual gfx::Size GetPreferredSize() {
283 out->cx = kScrollArrowHeight * 2 - 1; 284 return gfx::Size(kScrollArrowHeight * 2 - 1, pref_height_);
284 out->cy = pref_height_;
285 } 285 }
286 286
287 virtual bool CanDrop(const OSExchangeData& data) { 287 virtual bool CanDrop(const OSExchangeData& data) {
288 DCHECK(host_->GetMenuItem()->GetMenuController()); 288 DCHECK(host_->GetMenuItem()->GetMenuController());
289 return true; // Always return true so that drop events are targeted to us. 289 return true; // Always return true so that drop events are targeted to us.
290 } 290 }
291 291
292 virtual void OnDragEntered(const DropTargetEvent& event) { 292 virtual void OnDragEntered(const DropTargetEvent& event) {
293 DCHECK(host_->GetMenuItem()->GetMenuController()); 293 DCHECK(host_->GetMenuItem()->GetMenuController());
294 host_->GetMenuItem()->GetMenuController()->OnDragEnteredScrollButton( 294 host_->GetMenuItem()->GetMenuController()->OnDragEnteredScrollButton(
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 explicit MenuScrollView(View* child) { 360 explicit MenuScrollView(View* child) {
361 AddChildView(child); 361 AddChildView(child);
362 } 362 }
363 363
364 virtual void ScrollRectToVisible(int x, int y, int width, int height) { 364 virtual void ScrollRectToVisible(int x, int y, int width, int height) {
365 // NOTE: this assumes we only want to scroll in the y direction. 365 // NOTE: this assumes we only want to scroll in the y direction.
366 366
367 View* child = GetContents(); 367 View* child = GetContents();
368 // Convert y to view's coordinates. 368 // Convert y to view's coordinates.
369 y -= child->y(); 369 y -= child->y();
370 CSize pref; 370 gfx::Size pref = child->GetPreferredSize();
371 child->GetPreferredSize(&pref);
372 // Constrain y to make sure we don't show past the bottom of the view. 371 // Constrain y to make sure we don't show past the bottom of the view.
373 y = std::max(0, std::min(static_cast<int>(pref.cy) - this->height(), y)); 372 y = std::max(0, std::min(pref.height() - this->height(), y));
374 child->SetY(-y); 373 child->SetY(-y);
375 } 374 }
376 375
377 // Returns the contents, which is the SubmenuView. 376 // Returns the contents, which is the SubmenuView.
378 View* GetContents() { 377 View* GetContents() {
379 return GetChildViewAt(0); 378 return GetChildViewAt(0);
380 } 379 }
381 380
382 private: 381 private:
383 DISALLOW_EVIL_CONSTRUCTORS(MenuScrollView); 382 DISALLOW_EVIL_CONSTRUCTORS(MenuScrollView);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 int x = insets.left(); 420 int x = insets.left();
422 int y = insets.top(); 421 int y = insets.top();
423 int width = View::width() - insets.width(); 422 int width = View::width() - insets.width();
424 int content_height = height() - insets.height(); 423 int content_height = height() - insets.height();
425 if (!scroll_up_button_->IsVisible()) { 424 if (!scroll_up_button_->IsVisible()) {
426 scroll_view_->SetBounds(x, y, width, content_height); 425 scroll_view_->SetBounds(x, y, width, content_height);
427 scroll_view_->Layout(); 426 scroll_view_->Layout();
428 return; 427 return;
429 } 428 }
430 429
431 CSize pref; 430 gfx::Size pref = scroll_up_button_->GetPreferredSize();
432 scroll_up_button_->GetPreferredSize(&pref); 431 scroll_up_button_->SetBounds(x, y, width, pref.height());
433 scroll_up_button_->SetBounds(x, y, width, pref.cy); 432 content_height -= pref.height();
434 content_height -= pref.cy;
435 433
436 const int scroll_view_y = y + pref.cy; 434 const int scroll_view_y = y + pref.height();
437 435
438 scroll_down_button_->GetPreferredSize(&pref); 436 pref = scroll_down_button_->GetPreferredSize();
439 scroll_down_button_->SetBounds(x, height() - pref.cy - insets.top(), 437 scroll_down_button_->SetBounds(x, height() - pref.height() - insets.top(),
440 width, pref.cy); 438 width, pref.height());
441 content_height -= pref.cy; 439 content_height -= pref.height();
442 440
443 scroll_view_->SetBounds(x, scroll_view_y, width, content_height); 441 scroll_view_->SetBounds(x, scroll_view_y, width, content_height);
444 scroll_view_->Layout(); 442 scroll_view_->Layout();
445 } 443 }
446 444
447 virtual void DidChangeBounds(const CRect& previous, const CRect& current) { 445 virtual void DidChangeBounds(const CRect& previous, const CRect& current) {
448 CSize content_pref; 446 gfx::Size content_pref = scroll_view_->GetContents()->GetPreferredSize();
449 scroll_view_->GetContents()->GetPreferredSize(&content_pref); 447 scroll_up_button_->SetVisible(content_pref.height() > height());
450 scroll_up_button_->SetVisible(content_pref.cy > height()); 448 scroll_down_button_->SetVisible(content_pref.height() > height());
451 scroll_down_button_->SetVisible(content_pref.cy > height());
452 } 449 }
453 450
454 virtual void GetPreferredSize(CSize* out) { 451 virtual gfx::Size GetPreferredSize() {
455 scroll_view_->GetContents()->GetPreferredSize(out); 452 gfx::Size prefsize = scroll_view_->GetContents()->GetPreferredSize();
456 gfx::Insets insets = GetInsets(); 453 gfx::Insets insets = GetInsets();
457 out->cx += insets.width(); 454 prefsize.Enlarge(insets.width(), insets.height());
458 out->cy += insets.height(); 455 return prefsize;
459 } 456 }
460 457
461 private: 458 private:
462 // The scroll buttons. 459 // The scroll buttons.
463 View* scroll_up_button_; 460 View* scroll_up_button_;
464 View* scroll_down_button_; 461 View* scroll_down_button_;
465 462
466 // The scroll view. 463 // The scroll view.
467 MenuScrollView* scroll_view_; 464 MenuScrollView* scroll_view_;
468 465
(...skipping 24 matching lines...) Expand all
493 &gutter_bounds); 490 &gutter_bounds);
494 start_x = gutter_bounds.left + gutter_width; 491 start_x = gutter_bounds.left + gutter_width;
495 start_y = 0; 492 start_y = 0;
496 } 493 }
497 RECT separator_bounds = { start_x, start_y, width(), height() }; 494 RECT separator_bounds = { start_x, start_y, width(), height() };
498 NativeTheme::instance()->PaintMenuSeparator(dc, MENU_POPUPSEPARATOR, 495 NativeTheme::instance()->PaintMenuSeparator(dc, MENU_POPUPSEPARATOR,
499 MPI_NORMAL, &separator_bounds); 496 MPI_NORMAL, &separator_bounds);
500 canvas->endPlatformPaint(); 497 canvas->endPlatformPaint();
501 } 498 }
502 499
503 void GetPreferredSize(CSize* out) { 500 gfx::Size GetPreferredSize() {
504 out->cx = 10; // Just in case we're the only item in a menu. 501 return gfx::Size(10, // Just in case we're the only item in a menu.
505 out->cy = separator_height; 502 separator_height);
506 } 503 }
507 504
508 private: 505 private:
509 DISALLOW_EVIL_CONSTRUCTORS(MenuSeparator); 506 DISALLOW_EVIL_CONSTRUCTORS(MenuSeparator);
510 }; 507 };
511 508
512 // MenuHostRootView ---------------------------------------------------------- 509 // MenuHostRootView ----------------------------------------------------------
513 510
514 // MenuHostRootView is the RootView of the window showing the menu. 511 // MenuHostRootView is the RootView of the window showing the menu.
515 // SubmenuView's scroll view is added as a child of MenuHostRootView. 512 // SubmenuView's scroll view is added as a child of MenuHostRootView.
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 } 792 }
796 NOTREACHED(); 793 NOTREACHED();
797 return NULL; 794 return NULL;
798 } 795 }
799 796
800 void SubmenuView::Layout() { 797 void SubmenuView::Layout() {
801 // We're in a ScrollView, and need to set our width/height ourselves. 798 // We're in a ScrollView, and need to set our width/height ourselves.
802 View* parent = GetParent(); 799 View* parent = GetParent();
803 if (!parent) 800 if (!parent)
804 return; 801 return;
805 CSize pref; 802 SetBounds(x(), y(), parent->width(), GetPreferredSize().height());
806 GetPreferredSize(&pref);
807 SetBounds(x(), y(), parent->width(), pref.cy);
808 803
809 gfx::Insets insets = GetInsets(); 804 gfx::Insets insets = GetInsets();
810 int x = insets.left(); 805 int x = insets.left();
811 int y = insets.top(); 806 int y = insets.top();
812 int menu_item_width = width() - insets.width(); 807 int menu_item_width = width() - insets.width();
813 for (int i = 0; i < GetChildViewCount(); ++i) { 808 for (int i = 0; i < GetChildViewCount(); ++i) {
814 View* child = GetChildViewAt(i); 809 View* child = GetChildViewAt(i);
815 CSize child_pref_size; 810 gfx::Size child_pref_size = child->GetPreferredSize();
816 child->GetPreferredSize(&child_pref_size); 811 child->SetBounds(x, y, menu_item_width, child_pref_size.height());
817 child->SetBounds(x, y, menu_item_width, child_pref_size.cy); 812 y += child_pref_size.height();
818 y += child_pref_size.cy;
819 } 813 }
820 } 814 }
821 815
822 void SubmenuView::GetPreferredSize(CSize* out) { 816 gfx::Size SubmenuView::GetPreferredSize() {
823 if (GetChildViewCount() == 0) { 817 if (GetChildViewCount() == 0)
824 out->SetSize(0, 0); 818 return gfx::Size();
825 return;
826 }
827 819
828 int max_width = 0; 820 int max_width = 0;
829 int height = 0; 821 int height = 0;
830 for (int i = 0; i < GetChildViewCount(); ++i) { 822 for (int i = 0; i < GetChildViewCount(); ++i) {
831 View* child = GetChildViewAt(i); 823 View* child = GetChildViewAt(i);
832 CSize child_pref_size; 824 gfx::Size child_pref_size = child->GetPreferredSize();
833 child->GetPreferredSize(&child_pref_size); 825 max_width = std::max(max_width, child_pref_size.width());
834 max_width = std::max(max_width, static_cast<int>(child_pref_size.cx)); 826 height += child_pref_size.height();
835 height += child_pref_size.cy;
836 } 827 }
837 gfx::Insets insets = GetInsets(); 828 gfx::Insets insets = GetInsets();
838 out->SetSize(max_width + insets.width(), height + insets.height()); 829 return gfx::Size(max_width + insets.width(), height + insets.height());
839 } 830 }
840 831
841 void SubmenuView::DidChangeBounds(const CRect& previous, const CRect& current) { 832 void SubmenuView::DidChangeBounds(const CRect& previous, const CRect& current) {
842 SchedulePaint(); 833 SchedulePaint();
843 } 834 }
844 835
845 void SubmenuView::PaintChildren(ChromeCanvas* canvas) { 836 void SubmenuView::PaintChildren(ChromeCanvas* canvas) {
846 View::PaintChildren(canvas); 837 View::PaintChildren(canvas);
847 838
848 if (drop_item_ && drop_position_ != MenuDelegate::DROP_ON) 839 if (drop_item_ && drop_position_ != MenuDelegate::DROP_ON)
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 1149
1159 void MenuItemView::SetIcon(const SkBitmap& icon) { 1150 void MenuItemView::SetIcon(const SkBitmap& icon) {
1160 icon_ = icon; 1151 icon_ = icon;
1161 SchedulePaint(); 1152 SchedulePaint();
1162 } 1153 }
1163 1154
1164 void MenuItemView::Paint(ChromeCanvas* canvas) { 1155 void MenuItemView::Paint(ChromeCanvas* canvas) {
1165 Paint(canvas, false); 1156 Paint(canvas, false);
1166 } 1157 }
1167 1158
1168 void MenuItemView::GetPreferredSize(CSize* out) { 1159 gfx::Size MenuItemView::GetPreferredSize() {
1169 out->cx = font_.GetStringWidth(title_) + label_start + item_right_margin; 1160 return gfx::Size(
1170 out->cy = font_.height() + kItemBottomMargin + kItemTopMargin; 1161 font_.GetStringWidth(title_) + label_start + item_right_margin,
1162 font_.height() + kItemBottomMargin + kItemTopMargin);
1171 } 1163 }
1172 1164
1173 MenuController* MenuItemView::GetMenuController() { 1165 MenuController* MenuItemView::GetMenuController() {
1174 return GetRootMenuItem()->controller_; 1166 return GetRootMenuItem()->controller_;
1175 } 1167 }
1176 1168
1177 MenuDelegate* MenuItemView::GetDelegate() { 1169 MenuDelegate* MenuItemView::GetDelegate() {
1178 return GetRootMenuItem()->delegate_; 1170 return GetRootMenuItem()->delegate_;
1179 } 1171 }
1180 1172
(...skipping 1227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2408 } 2400 }
2409 2401
2410 gfx::Rect MenuController::CalculateMenuBounds(MenuItemView* item, 2402 gfx::Rect MenuController::CalculateMenuBounds(MenuItemView* item,
2411 bool prefer_leading, 2403 bool prefer_leading,
2412 bool* is_leading) { 2404 bool* is_leading) {
2413 DCHECK(item); 2405 DCHECK(item);
2414 2406
2415 SubmenuView* submenu = item->GetSubmenu(); 2407 SubmenuView* submenu = item->GetSubmenu();
2416 DCHECK(submenu); 2408 DCHECK(submenu);
2417 2409
2418 CSize pref; 2410 gfx::Size pref = submenu->GetScrollViewContainer()->GetPreferredSize();
2419 submenu->GetScrollViewContainer()->GetPreferredSize(&pref);
2420 2411
2421 // Don't let the menu go to wide. This is some where between what IE and FF 2412 // Don't let the menu go to wide. This is some where between what IE and FF
2422 // do. 2413 // do.
2423 pref.cx = std::min(pref.cx, kMaxMenuWidth); 2414 pref.set_width(std::min(pref.width(), kMaxMenuWidth));
2424 if (!state_.monitor_bounds.IsEmpty()) 2415 if (!state_.monitor_bounds.IsEmpty())
2425 pref.cx = std::min(pref.cx, 2416 pref.set_width(std::min(pref.width(), state_.monitor_bounds.width()));
2426 static_cast<LONG>(state_.monitor_bounds.width()));
2427 2417
2428 // Assume we can honor prefer_leading. 2418 // Assume we can honor prefer_leading.
2429 *is_leading = prefer_leading; 2419 *is_leading = prefer_leading;
2430 2420
2431 int x, y; 2421 int x, y;
2432 2422
2433 if (!item->GetParentMenuItem()) { 2423 if (!item->GetParentMenuItem()) {
2434 // First item, position relative to initial location. 2424 // First item, position relative to initial location.
2435 x = state_.initial_bounds.x(); 2425 x = state_.initial_bounds.x();
2436 y = state_.initial_bounds.bottom(); 2426 y = state_.initial_bounds.bottom();
2437 if (state_.anchor == MenuItemView::TOPRIGHT) 2427 if (state_.anchor == MenuItemView::TOPRIGHT)
2438 x = x + state_.initial_bounds.width() - pref.cx; 2428 x = x + state_.initial_bounds.width() - pref.width();
2439 if (!state_.monitor_bounds.IsEmpty() && 2429 if (!state_.monitor_bounds.IsEmpty() &&
2440 y + pref.cy > state_.monitor_bounds.bottom()) { 2430 y + pref.height() > state_.monitor_bounds.bottom()) {
2441 // The menu doesn't fit on screen. If the first location is above the 2431 // The menu doesn't fit on screen. If the first location is above the
2442 // half way point, show from the mouse location to bottom of screen. 2432 // half way point, show from the mouse location to bottom of screen.
2443 // Otherwise show from the top of the screen to the location of the mouse. 2433 // Otherwise show from the top of the screen to the location of the mouse.
2444 // While odd, this behavior matches IE. 2434 // While odd, this behavior matches IE.
2445 if (y < (state_.monitor_bounds.y() + 2435 if (y < (state_.monitor_bounds.y() +
2446 state_.monitor_bounds.height() / 2)) { 2436 state_.monitor_bounds.height() / 2)) {
2447 pref.cy = std::min(pref.cy, 2437 pref.set_height(std::min(pref.height(),
2448 static_cast<LONG>(state_.monitor_bounds.bottom() - y)); 2438 state_.monitor_bounds.bottom() - y));
2449 } else { 2439 } else {
2450 pref.cy = std::min(pref.cy, static_cast<LONG>( 2440 pref.set_height(std::min(pref.height(),
2451 state_.initial_bounds.y() - state_.monitor_bounds.y())); 2441 state_.initial_bounds.y() - state_.monitor_bounds.y()));
2452 y = state_.initial_bounds.y() - pref.cy; 2442 y = state_.initial_bounds.y() - pref.height();
2453 } 2443 }
2454 } 2444 }
2455 } else { 2445 } else {
2456 // Not the first menu; position it relative to the bounds of the menu 2446 // Not the first menu; position it relative to the bounds of the menu
2457 // item. 2447 // item.
2458 gfx::Point item_loc; 2448 gfx::Point item_loc;
2459 View::ConvertPointToScreen(item, &item_loc); 2449 View::ConvertPointToScreen(item, &item_loc);
2460 2450
2461 // We must make sure we take into account the UI layout. If the layout is 2451 // We must make sure we take into account the UI layout. If the layout is
2462 // RTL, then a 'leading' menu is positioned to the left of the parent menu 2452 // RTL, then a 'leading' menu is positioned to the left of the parent menu
2463 // item and not to the right. 2453 // item and not to the right.
2464 bool layout_is_rtl = item->UILayoutIsRightToLeft(); 2454 bool layout_is_rtl = item->UILayoutIsRightToLeft();
2465 bool create_on_the_right = (prefer_leading && !layout_is_rtl) || 2455 bool create_on_the_right = (prefer_leading && !layout_is_rtl) ||
2466 (!prefer_leading && layout_is_rtl); 2456 (!prefer_leading && layout_is_rtl);
2467 2457
2468 if (create_on_the_right) { 2458 if (create_on_the_right) {
2469 x = item_loc.x() + item->width() - kSubmenuHorizontalInset; 2459 x = item_loc.x() + item->width() - kSubmenuHorizontalInset;
2470 if (state_.monitor_bounds.width() != 0 && 2460 if (state_.monitor_bounds.width() != 0 &&
2471 x + pref.cx > state_.monitor_bounds.right()) { 2461 x + pref.width() > state_.monitor_bounds.right()) {
2472 if (layout_is_rtl) 2462 if (layout_is_rtl)
2473 *is_leading = true; 2463 *is_leading = true;
2474 else 2464 else
2475 *is_leading = false; 2465 *is_leading = false;
2476 x = item_loc.x() - pref.cx + kSubmenuHorizontalInset; 2466 x = item_loc.x() - pref.width() + kSubmenuHorizontalInset;
2477 } 2467 }
2478 } else { 2468 } else {
2479 x = item_loc.x() - pref.cx + kSubmenuHorizontalInset; 2469 x = item_loc.x() - pref.width() + kSubmenuHorizontalInset;
2480 if (state_.monitor_bounds.width() != 0 && x < state_.monitor_bounds.x()) { 2470 if (state_.monitor_bounds.width() != 0 && x < state_.monitor_bounds.x()) {
2481 if (layout_is_rtl) 2471 if (layout_is_rtl)
2482 *is_leading = false; 2472 *is_leading = false;
2483 else 2473 else
2484 *is_leading = true; 2474 *is_leading = true;
2485 x = item_loc.x() + item->width() - kSubmenuHorizontalInset; 2475 x = item_loc.x() + item->width() - kSubmenuHorizontalInset;
2486 } 2476 }
2487 } 2477 }
2488 y = item_loc.y() - kSubmenuBorderSize; 2478 y = item_loc.y() - kSubmenuBorderSize;
2489 if (state_.monitor_bounds.width() != 0) { 2479 if (state_.monitor_bounds.width() != 0) {
2490 pref.cy = std::min(pref.cy, 2480 pref.set_height(std::min(pref.height(), state_.monitor_bounds.height()));
2491 static_cast<LONG>(state_.monitor_bounds.height())); 2481 if (y + pref.height() > state_.monitor_bounds.bottom())
2492 if (y + pref.cy > state_.monitor_bounds.bottom()) 2482 y = state_.monitor_bounds.bottom() - pref.height();
2493 y = state_.monitor_bounds.bottom() - pref.cy;
2494 if (y < state_.monitor_bounds.y()) 2483 if (y < state_.monitor_bounds.y())
2495 y = state_.monitor_bounds.y(); 2484 y = state_.monitor_bounds.y();
2496 } 2485 }
2497 } 2486 }
2498 2487
2499 if (state_.monitor_bounds.width() != 0) { 2488 if (state_.monitor_bounds.width() != 0) {
2500 if (x + pref.cx > state_.monitor_bounds.right()) 2489 if (x + pref.width() > state_.monitor_bounds.right())
2501 x = state_.monitor_bounds.right() - pref.cx; 2490 x = state_.monitor_bounds.right() - pref.width();
2502 if (x < state_.monitor_bounds.x()) 2491 if (x < state_.monitor_bounds.x())
2503 x = state_.monitor_bounds.x(); 2492 x = state_.monitor_bounds.x();
2504 } 2493 }
2505 return gfx::Rect(x, y, pref.cx, pref.cy); 2494 return gfx::Rect(x, y, pref.width(), pref.height());
2506 } 2495 }
2507 2496
2508 // static 2497 // static
2509 int MenuController::MenuDepth(MenuItemView* item) { 2498 int MenuController::MenuDepth(MenuItemView* item) {
2510 if (!item) 2499 if (!item)
2511 return 0; 2500 return 0;
2512 return MenuDepth(item->GetParentMenuItem()) + 1; 2501 return MenuDepth(item->GetParentMenuItem()) + 1;
2513 } 2502 }
2514 2503
2515 void MenuController::IncrementSelection(int delta) { 2504 void MenuController::IncrementSelection(int delta) {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
2723 scroll_task_.reset(new MenuScrollTask()); 2712 scroll_task_.reset(new MenuScrollTask());
2724 scroll_task_->Update(part); 2713 scroll_task_->Update(part);
2725 } 2714 }
2726 2715
2727 void MenuController::StopScrolling() { 2716 void MenuController::StopScrolling() {
2728 scroll_task_.reset(NULL); 2717 scroll_task_.reset(NULL);
2729 } 2718 }
2730 2719
2731 } // namespace ChromeViews 2720 } // namespace ChromeViews
2732 2721
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698