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

Side by Side Diff: trunk/src/ui/views/window/custom_frame_view.cc

Issue 294473016: Revert 272352 "Reland Linux Window Control Alignment" (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 7 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) 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
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
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
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
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
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
OLDNEW
« no previous file with comments | « trunk/src/ui/views/window/custom_frame_view.h ('k') | trunk/src/ui/views/window/custom_frame_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698