OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ui/views/window/custom_frame_view.h" | 5 #include "ui/views/window/custom_frame_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | |
9 | 8 |
10 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
11 #include "grit/ui_resources.h" | 10 #include "grit/ui_resources.h" |
12 #include "grit/ui_strings.h" | 11 #include "grit/ui_strings.h" |
13 #include "ui/base/hit_test.h" | 12 #include "ui/base/hit_test.h" |
14 #include "ui/base/l10n/l10n_util.h" | 13 #include "ui/base/l10n/l10n_util.h" |
15 #include "ui/base/resource/resource_bundle.h" | 14 #include "ui/base/resource/resource_bundle.h" |
16 #include "ui/gfx/canvas.h" | 15 #include "ui/gfx/canvas.h" |
17 #include "ui/gfx/font.h" | 16 #include "ui/gfx/font.h" |
18 #include "ui/gfx/image/image.h" | 17 #include "ui/gfx/image/image.h" |
19 #include "ui/gfx/path.h" | 18 #include "ui/gfx/path.h" |
20 #include "ui/gfx/rect.h" | |
21 #include "ui/views/color_constants.h" | 19 #include "ui/views/color_constants.h" |
22 #include "ui/views/controls/button/image_button.h" | 20 #include "ui/views/controls/button/image_button.h" |
23 #include "ui/views/views_delegate.h" | 21 #include "ui/views/views_delegate.h" |
24 #include "ui/views/widget/native_widget_private.h" | 22 #include "ui/views/widget/native_widget_private.h" |
25 #include "ui/views/widget/widget.h" | 23 #include "ui/views/widget/widget.h" |
26 #include "ui/views/widget/widget_delegate.h" | 24 #include "ui/views/widget/widget_delegate.h" |
27 #include "ui/views/window/client_view.h" | 25 #include "ui/views/window/client_view.h" |
28 #include "ui/views/window/frame_background.h" | 26 #include "ui/views/window/frame_background.h" |
29 #include "ui/views/window/window_button_order_provider.h" | |
30 #include "ui/views/window/window_resources.h" | 27 #include "ui/views/window/window_resources.h" |
31 #include "ui/views/window/window_shape.h" | 28 #include "ui/views/window/window_shape.h" |
32 | 29 |
33 namespace views { | 30 namespace views { |
34 | 31 |
35 namespace { | 32 namespace { |
36 | 33 |
37 // The frame border is only visible in restored mode and is hardcoded to 4 px on | 34 // The frame border is only visible in restored mode and is hardcoded to 4 px on |
38 // each side regardless of the system window border size. | 35 // each side regardless of the system window border size. |
39 const int kFrameBorderThickness = 4; | 36 const int kFrameBorderThickness = 4; |
(...skipping 23 matching lines...) Expand all Loading... |
63 const SkColor kDefaultColorFrame = SkColorSetRGB(66, 116, 201); | 60 const SkColor kDefaultColorFrame = SkColorSetRGB(66, 116, 201); |
64 const SkColor kDefaultColorFrameInactive = SkColorSetRGB(161, 182, 228); | 61 const SkColor kDefaultColorFrameInactive = SkColorSetRGB(161, 182, 228); |
65 #endif | 62 #endif |
66 | 63 |
67 const gfx::FontList& GetTitleFontList() { | 64 const gfx::FontList& GetTitleFontList() { |
68 static const gfx::FontList title_font_list = | 65 static const gfx::FontList title_font_list = |
69 internal::NativeWidgetPrivate::GetWindowTitleFontList(); | 66 internal::NativeWidgetPrivate::GetWindowTitleFontList(); |
70 return title_font_list; | 67 return title_font_list; |
71 } | 68 } |
72 | 69 |
73 void LayoutButton(ImageButton* button, const gfx::Rect& bounds) { | |
74 button->SetVisible(true); | |
75 button->SetImageAlignment(ImageButton::ALIGN_LEFT, | |
76 ImageButton::ALIGN_BOTTOM); | |
77 button->SetBoundsRect(bounds); | |
78 } | |
79 | |
80 } // namespace | 70 } // namespace |
81 | 71 |
82 /////////////////////////////////////////////////////////////////////////////// | 72 /////////////////////////////////////////////////////////////////////////////// |
83 // CustomFrameView, public: | 73 // CustomFrameView, public: |
84 | 74 |
85 CustomFrameView::CustomFrameView() | 75 CustomFrameView::CustomFrameView() |
86 : frame_(NULL), | 76 : frame_(NULL), |
87 window_icon_(NULL), | 77 window_icon_(NULL), |
88 minimize_button_(NULL), | 78 minimize_button_(NULL), |
89 maximize_button_(NULL), | 79 maximize_button_(NULL), |
90 restore_button_(NULL), | 80 restore_button_(NULL), |
91 close_button_(NULL), | 81 close_button_(NULL), |
92 should_show_maximize_button_(false), | 82 should_show_maximize_button_(false), |
93 frame_background_(new FrameBackground()), | 83 frame_background_(new FrameBackground()) { |
94 minimum_title_bar_x_(0), | |
95 maximum_title_bar_x_(-1) { | |
96 } | 84 } |
97 | 85 |
98 CustomFrameView::~CustomFrameView() { | 86 CustomFrameView::~CustomFrameView() { |
99 } | 87 } |
100 | 88 |
101 void CustomFrameView::Init(Widget* frame) { | 89 void CustomFrameView::Init(Widget* frame) { |
102 frame_ = frame; | 90 frame_ = frame; |
103 | 91 |
104 close_button_ = InitWindowCaptionButton(IDS_APP_ACCNAME_CLOSE, | 92 close_button_ = new ImageButton(this); |
105 IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P); | 93 close_button_->SetAccessibleName( |
| 94 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE)); |
| 95 |
| 96 // Close button images will be set in LayoutWindowControls(). |
| 97 AddChildView(close_button_); |
| 98 |
106 minimize_button_ = InitWindowCaptionButton(IDS_APP_ACCNAME_MINIMIZE, | 99 minimize_button_ = InitWindowCaptionButton(IDS_APP_ACCNAME_MINIMIZE, |
107 IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P); | 100 IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P); |
| 101 |
108 maximize_button_ = InitWindowCaptionButton(IDS_APP_ACCNAME_MAXIMIZE, | 102 maximize_button_ = InitWindowCaptionButton(IDS_APP_ACCNAME_MAXIMIZE, |
109 IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P); | 103 IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P); |
| 104 |
110 restore_button_ = InitWindowCaptionButton(IDS_APP_ACCNAME_RESTORE, | 105 restore_button_ = InitWindowCaptionButton(IDS_APP_ACCNAME_RESTORE, |
111 IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P); | 106 IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P); |
112 | 107 |
113 should_show_maximize_button_ = frame_->widget_delegate()->CanMaximize(); | 108 should_show_maximize_button_ = frame_->widget_delegate()->CanMaximize(); |
114 | 109 |
115 if (frame_->widget_delegate()->ShouldShowWindowIcon()) { | 110 if (frame_->widget_delegate()->ShouldShowWindowIcon()) { |
116 window_icon_ = new ImageButton(this); | 111 window_icon_ = new ImageButton(this); |
117 AddChildView(window_icon_); | 112 AddChildView(window_icon_); |
118 } | 113 } |
119 } | 114 } |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 | 269 |
275 int CustomFrameView::NonClientTopBorderHeight() const { | 270 int CustomFrameView::NonClientTopBorderHeight() const { |
276 return std::max(FrameBorderThickness() + IconSize(), | 271 return std::max(FrameBorderThickness() + IconSize(), |
277 CaptionButtonY() + kCaptionButtonHeightWithPadding) + | 272 CaptionButtonY() + kCaptionButtonHeightWithPadding) + |
278 TitlebarBottomThickness(); | 273 TitlebarBottomThickness(); |
279 } | 274 } |
280 | 275 |
281 int CustomFrameView::CaptionButtonY() const { | 276 int CustomFrameView::CaptionButtonY() const { |
282 // Maximized buttons start at window top so that even if their images aren't | 277 // Maximized buttons start at window top so that even if their images aren't |
283 // drawn flush with the screen edge, they still obey Fitts' Law. | 278 // drawn flush with the screen edge, they still obey Fitts' Law. |
284 return frame_->IsMaximized() ? FrameBorderThickness() : kFrameBorderThickness; | 279 return frame_->IsMaximized() ? FrameBorderThickness() : kFrameShadowThickness; |
285 } | 280 } |
286 | 281 |
287 int CustomFrameView::TitlebarBottomThickness() const { | 282 int CustomFrameView::TitlebarBottomThickness() const { |
288 return kTitlebarTopAndBottomEdgeThickness + | 283 return kTitlebarTopAndBottomEdgeThickness + |
289 (ShouldShowClientEdge() ? kClientEdgeThickness : 0); | 284 (ShouldShowClientEdge() ? kClientEdgeThickness : 0); |
290 } | 285 } |
291 | 286 |
292 int CustomFrameView::IconSize() const { | 287 int CustomFrameView::IconSize() const { |
293 #if defined(OS_WIN) | 288 #if defined(OS_WIN) |
294 // This metric scales up if either the titlebar height or the titlebar font | 289 // This metric scales up if either the titlebar height or the titlebar font |
(...skipping 17 matching lines...) Expand all Loading... |
312 // from below the 3D edge. | 307 // from below the 3D edge. |
313 int unavailable_px_at_top = frame_->IsMaximized() ? | 308 int unavailable_px_at_top = frame_->IsMaximized() ? |
314 frame_thickness : kTitlebarTopAndBottomEdgeThickness; | 309 frame_thickness : kTitlebarTopAndBottomEdgeThickness; |
315 // When the icon is shorter than the minimum space we reserve for the caption | 310 // When the icon is shorter than the minimum space we reserve for the caption |
316 // button, we vertically center it. We want to bias rounding to put extra | 311 // button, we vertically center it. We want to bias rounding to put extra |
317 // space above the icon, since the 3D edge (+ client edge, for restored | 312 // space above the icon, since the 3D edge (+ client edge, for restored |
318 // windows) below looks (to the eye) more like additional space than does the | 313 // windows) below looks (to the eye) more like additional space than does the |
319 // 3D edge (or nothing at all, for maximized windows) above; hence the +1. | 314 // 3D edge (or nothing at all, for maximized windows) above; hence the +1. |
320 int y = unavailable_px_at_top + (NonClientTopBorderHeight() - | 315 int y = unavailable_px_at_top + (NonClientTopBorderHeight() - |
321 unavailable_px_at_top - size - TitlebarBottomThickness() + 1) / 2; | 316 unavailable_px_at_top - size - TitlebarBottomThickness() + 1) / 2; |
322 return gfx::Rect(frame_thickness + kIconLeftSpacing + minimum_title_bar_x_, | 317 return gfx::Rect(frame_thickness + kIconLeftSpacing, y, size, size); |
323 y, size, size); | |
324 } | 318 } |
325 | 319 |
326 bool CustomFrameView::ShouldShowTitleBarAndBorder() const { | 320 bool CustomFrameView::ShouldShowTitleBarAndBorder() const { |
327 if (frame_->IsFullscreen()) | 321 if (frame_->IsFullscreen()) |
328 return false; | 322 return false; |
329 | 323 |
330 if (ViewsDelegate::views_delegate) { | 324 if (ViewsDelegate::views_delegate) { |
331 return !ViewsDelegate::views_delegate->WindowManagerProvidesTitleBar( | 325 return !ViewsDelegate::views_delegate->WindowManagerProvidesTitleBar( |
332 frame_->IsMaximized()); | 326 frame_->IsMaximized()); |
333 } | 327 } |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 SkColor CustomFrameView::GetFrameColor() const { | 461 SkColor CustomFrameView::GetFrameColor() const { |
468 return frame_->IsActive() ? kDefaultColorFrame : kDefaultColorFrameInactive; | 462 return frame_->IsActive() ? kDefaultColorFrame : kDefaultColorFrameInactive; |
469 } | 463 } |
470 | 464 |
471 const gfx::ImageSkia* CustomFrameView::GetFrameImage() const { | 465 const gfx::ImageSkia* CustomFrameView::GetFrameImage() const { |
472 return ui::ResourceBundle::GetSharedInstance().GetImageNamed( | 466 return ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
473 frame_->IsActive() ? IDR_FRAME : IDR_FRAME_INACTIVE).ToImageSkia(); | 467 frame_->IsActive() ? IDR_FRAME : IDR_FRAME_INACTIVE).ToImageSkia(); |
474 } | 468 } |
475 | 469 |
476 void CustomFrameView::LayoutWindowControls() { | 470 void CustomFrameView::LayoutWindowControls() { |
477 minimum_title_bar_x_ = 0; | 471 close_button_->SetImageAlignment(ImageButton::ALIGN_LEFT, |
478 maximum_title_bar_x_ = width(); | 472 ImageButton::ALIGN_BOTTOM); |
479 | |
480 if (bounds().IsEmpty()) | |
481 return; | |
482 | |
483 int caption_y = CaptionButtonY(); | 473 int caption_y = CaptionButtonY(); |
484 bool is_maximized = frame_->IsMaximized(); | 474 bool is_maximized = frame_->IsMaximized(); |
485 // There should always be the same number of non-shadow pixels visible to the | 475 // There should always be the same number of non-shadow pixels visible to the |
486 // side of the caption buttons. In maximized mode we extend the edge button | 476 // side of the caption buttons. In maximized mode we extend the rightmost |
487 // to the screen corner to obey Fitts' Law. | 477 // button to the screen corner to obey Fitts' Law. |
488 int extra_width = is_maximized ? | 478 int right_extra_width = is_maximized ? |
489 (kFrameBorderThickness - kFrameShadowThickness) : 0; | 479 (kFrameBorderThickness - kFrameShadowThickness) : 0; |
490 int next_button_x = FrameBorderThickness(); | 480 gfx::Size close_button_size = close_button_->GetPreferredSize(); |
| 481 close_button_->SetBounds(width() - FrameBorderThickness() - |
| 482 right_extra_width - close_button_size.width(), caption_y, |
| 483 close_button_size.width() + right_extra_width, |
| 484 close_button_size.height()); |
491 | 485 |
| 486 // When the window is restored, we show a maximized button; otherwise, we show |
| 487 // a restore button. |
492 bool is_restored = !is_maximized && !frame_->IsMinimized(); | 488 bool is_restored = !is_maximized && !frame_->IsMinimized(); |
493 ImageButton* invisible_button = is_restored ? restore_button_ | 489 ImageButton* invisible_button = is_restored ? restore_button_ |
494 : maximize_button_; | 490 : maximize_button_; |
495 invisible_button->SetVisible(false); | 491 invisible_button->SetVisible(false); |
496 | 492 |
497 WindowButtonOrderProvider* button_order = | 493 ImageButton* visible_button = is_restored ? maximize_button_ |
498 WindowButtonOrderProvider::GetInstance(); | 494 : restore_button_; |
499 const std::vector<views::FrameButton>& leading_buttons = | 495 FramePartImage normal_part, hot_part, pushed_part; |
500 button_order->leading_buttons(); | 496 int next_button_x; |
501 const std::vector<views::FrameButton>& trailing_buttons = | 497 if (should_show_maximize_button_) { |
502 button_order->trailing_buttons(); | 498 visible_button->SetVisible(true); |
503 | 499 visible_button->SetImageAlignment(ImageButton::ALIGN_LEFT, |
504 ImageButton* button = NULL; | 500 ImageButton::ALIGN_BOTTOM); |
505 for (std::vector<views::FrameButton>::const_iterator it = | 501 gfx::Size visible_button_size = visible_button->GetPreferredSize(); |
506 leading_buttons.begin(); it != leading_buttons.end(); ++it) { | 502 visible_button->SetBounds(close_button_->x() - visible_button_size.width(), |
507 button = GetImageButton(*it); | 503 caption_y, visible_button_size.width(), |
508 if (!button) | 504 visible_button_size.height()); |
509 continue; | 505 next_button_x = visible_button->x(); |
510 gfx::Rect target_bounds(gfx::Point(next_button_x, caption_y), | 506 } else { |
511 button->GetPreferredSize()); | 507 visible_button->SetVisible(false); |
512 if (it == leading_buttons.begin()) | 508 next_button_x = close_button_->x(); |
513 target_bounds.set_width(target_bounds.width() + extra_width); | |
514 LayoutButton(button, target_bounds); | |
515 next_button_x += button->width(); | |
516 minimum_title_bar_x_ = std::min(width(), next_button_x); | |
517 } | 509 } |
518 | 510 |
519 // Trailing buttions are laid out in a RTL fashion | 511 minimize_button_->SetVisible(true); |
520 next_button_x = width() - FrameBorderThickness(); | 512 minimize_button_->SetImageAlignment(ImageButton::ALIGN_LEFT, |
521 for (std::vector<views::FrameButton>::const_reverse_iterator it = | 513 ImageButton::ALIGN_BOTTOM); |
522 trailing_buttons.rbegin(); it != trailing_buttons.rend(); ++it) { | 514 gfx::Size minimize_button_size = minimize_button_->GetPreferredSize(); |
523 button = GetImageButton(*it); | 515 minimize_button_->SetBounds( |
524 if (!button) | 516 next_button_x - minimize_button_size.width(), caption_y, |
525 continue; | 517 minimize_button_size.width(), |
526 gfx::Rect target_bounds(gfx::Point(next_button_x, caption_y), | 518 minimize_button_size.height()); |
527 button->GetPreferredSize()); | 519 |
528 if (it == trailing_buttons.rbegin()) | 520 normal_part = IDR_CLOSE; |
529 target_bounds.set_width(target_bounds.width() + extra_width); | 521 hot_part = IDR_CLOSE_H; |
530 target_bounds.Offset(-target_bounds.width(), 0); | 522 pushed_part = IDR_CLOSE_P; |
531 LayoutButton(button, target_bounds); | 523 |
532 next_button_x = button->x(); | 524 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
533 maximum_title_bar_x_ = std::max(minimum_title_bar_x_, next_button_x); | 525 |
534 } | 526 close_button_->SetImage(CustomButton::STATE_NORMAL, |
| 527 rb.GetImageNamed(normal_part).ToImageSkia()); |
| 528 close_button_->SetImage(CustomButton::STATE_HOVERED, |
| 529 rb.GetImageNamed(hot_part).ToImageSkia()); |
| 530 close_button_->SetImage(CustomButton::STATE_PRESSED, |
| 531 rb.GetImageNamed(pushed_part).ToImageSkia()); |
535 } | 532 } |
536 | 533 |
537 void CustomFrameView::LayoutTitleBar() { | 534 void CustomFrameView::LayoutTitleBar() { |
538 DCHECK_GE(maximum_title_bar_x_, 0); | |
539 // The window title position is calculated based on the icon position, even | 535 // The window title position is calculated based on the icon position, even |
540 // when there is no icon. | 536 // when there is no icon. |
541 gfx::Rect icon_bounds(IconBounds()); | 537 gfx::Rect icon_bounds(IconBounds()); |
542 bool show_window_icon = window_icon_ != NULL; | 538 bool show_window_icon = window_icon_ != NULL; |
543 if (show_window_icon) | 539 if (show_window_icon) |
544 window_icon_->SetBoundsRect(icon_bounds); | 540 window_icon_->SetBoundsRect(icon_bounds); |
545 | 541 |
546 if (!frame_->widget_delegate()->ShouldShowWindowTitle()) | 542 if (!frame_->widget_delegate()->ShouldShowWindowTitle()) |
547 return; | 543 return; |
548 | 544 |
549 // The offset between the window left edge and the title text. | 545 // The offset between the window left edge and the title text. |
550 int title_x = show_window_icon ? icon_bounds.right() + kTitleIconOffsetX | 546 int title_x = show_window_icon ? icon_bounds.right() + kTitleIconOffsetX |
551 : icon_bounds.x(); | 547 : icon_bounds.x(); |
552 int title_height = GetTitleFontList().GetHeight(); | 548 int title_height = GetTitleFontList().GetHeight(); |
553 // We bias the title position so that when the difference between the icon and | 549 // We bias the title position so that when the difference between the icon and |
554 // title heights is odd, the extra pixel of the title is above the vertical | 550 // title heights is odd, the extra pixel of the title is above the vertical |
555 // midline rather than below. This compensates for how the icon is already | 551 // midline rather than below. This compensates for how the icon is already |
556 // biased downwards (see IconBounds()) and helps prevent descenders on the | 552 // biased downwards (see IconBounds()) and helps prevent descenders on the |
557 // title from overlapping the 3D edge at the bottom of the titlebar. | 553 // title from overlapping the 3D edge at the bottom of the titlebar. |
558 title_bounds_.SetRect(title_x, | 554 title_bounds_.SetRect(title_x, |
559 icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2), | 555 icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2), |
560 std::max(0, maximum_title_bar_x_ - kTitleCaptionSpacing - | 556 std::max(0, minimize_button_->x() - kTitleCaptionSpacing - |
561 title_x), title_height); | 557 title_x), title_height); |
562 } | 558 } |
563 | 559 |
564 void CustomFrameView::LayoutClientView() { | 560 void CustomFrameView::LayoutClientView() { |
565 if (!ShouldShowTitleBarAndBorder()) { | 561 if (!ShouldShowTitleBarAndBorder()) { |
566 client_view_bounds_ = bounds(); | 562 client_view_bounds_ = bounds(); |
567 return; | 563 return; |
568 } | 564 } |
569 | 565 |
570 int top_height = NonClientTopBorderHeight(); | 566 int top_height = NonClientTopBorderHeight(); |
(...skipping 14 matching lines...) Expand all Loading... |
585 button->SetImage(CustomButton::STATE_NORMAL, | 581 button->SetImage(CustomButton::STATE_NORMAL, |
586 rb.GetImageNamed(normal_image_id).ToImageSkia()); | 582 rb.GetImageNamed(normal_image_id).ToImageSkia()); |
587 button->SetImage(CustomButton::STATE_HOVERED, | 583 button->SetImage(CustomButton::STATE_HOVERED, |
588 rb.GetImageNamed(hot_image_id).ToImageSkia()); | 584 rb.GetImageNamed(hot_image_id).ToImageSkia()); |
589 button->SetImage(CustomButton::STATE_PRESSED, | 585 button->SetImage(CustomButton::STATE_PRESSED, |
590 rb.GetImageNamed(pushed_image_id).ToImageSkia()); | 586 rb.GetImageNamed(pushed_image_id).ToImageSkia()); |
591 AddChildView(button); | 587 AddChildView(button); |
592 return button; | 588 return button; |
593 } | 589 } |
594 | 590 |
595 ImageButton* CustomFrameView::GetImageButton(views::FrameButton frame_button) { | |
596 ImageButton* button = NULL; | |
597 switch (frame_button) { | |
598 case views::FRAME_BUTTON_MINIMIZE: { | |
599 button = minimize_button_; | |
600 break; | |
601 } | |
602 case views::FRAME_BUTTON_MAXIMIZE: { | |
603 bool is_restored = !frame_->IsMaximized() && !frame_->IsMinimized(); | |
604 button = is_restored ? maximize_button_ : restore_button_; | |
605 if (!should_show_maximize_button_) { | |
606 // If we should not show the maximize/restore button, then we return | |
607 // NULL as we don't want this button to become visible and to be laid | |
608 // out. | |
609 button->SetVisible(false); | |
610 return NULL; | |
611 } | |
612 break; | |
613 } | |
614 case views::FRAME_BUTTON_CLOSE: { | |
615 button = close_button_; | |
616 break; | |
617 } | |
618 } | |
619 return button; | |
620 } | |
621 | |
622 } // namespace views | 591 } // namespace views |
OLD | NEW |